Back to Features

한마음과학원

기간:2023.06 – 2023.10
Team:FrontEnd 2명 (본인 포함), BackEnd 1명 (본인)

1. 프로젝트 개요

Word 기반의 교재 데이터를 웹 서비스로 이관하고, 대용량 텍스트 검색 기능과 관리자 업로드 시스템을 구축한 프로젝트입니다. 1인 백엔드 개발자로서 교재 데이터 파싱 아키텍처 설계, RDBMS 기반 검색 최적화, 인증 로직 구현, CI/CD 배포 환경 구성까지 서버사이드 전반을 주도했습니다.

2. 문제 상황

1) 비정형 대용량 데이터의 DB화 과제

교재가 오직 Word 파일 형태로만 존재했으며, 이를 구조화하여 DB에 적재해야 했습니다. 최대 454페이지, 약 77만 자에 달하는 텍스트를 파싱하여 Insert 하는 과정에서 인스턴스 서버의 부하 및 데이터 무결성 훼손 리스크가 존재했습니다.

2) 검색 성능 및 정확도의 한계

단락 단위의 텍스트 검색 기능이 필수적이었으나, 기존 검색 방식은 응답 시간이 1500ms에 달해 UX를 크게 저해했습니다. 제한된 일정과 리소스 내에서 Elasticsearch 같은 전문 검색 엔진 도입 없이 빠르고 정확한 검색을 구현해야 했습니다.

3) 수동 배포로 인한 운영 리스크

수동 배포 과정에서 휴먼 에러 발생 가능성이 컸으며, 프로젝트 릴리즈 이후의 운영 안정성을 보장할 파이프라인이 부재했습니다.

3. 접근 전략

1) 정규식 기반 데이터 파싱 및 로컬 마이그레이션

Word 파일을 HTML로 변환 후 정규식 기반으로 구조화하는 전략을 세웠습니다. 특히 인스턴스 서버의 스펙 한계로 인한 다운타임을 방지하기 위해, 대용량 파싱 및 DB 적재 프로세스를 로컬 스크립트로 분리하여 실행하는 현실적인 마이그레이션 방안을 채택했습니다.

2) 하이브리드 검색 라우팅 (MySQL FULLTEXT + LIKE)

MySQL InnoDB의 FULLTEXT 기능을 최대한 활용하되, 최소 토큰 길이(innodb_ft_min_token_size) 제약을 백엔드 애플리케이션 레벨의 로직으로 보완하는 하이브리드 검색 아키텍처를 설계했습니다.

3) 운영 및 보안 안정성 확보

토큰 기반(Access/Refresh) 인증 및 쿠키 보안 설정을 적용하고, GitHub Actions를 활용해 무중단 자동 배포 환경을 구축하여 운영 효율성을 높였습니다.

4. 구체적 해결 과정

1) 3단계 정규식 패턴을 활용한 대용량 데이터 파싱

  • mammoth 라이브러리를 활용해 Word 문서를 HTML로 변환했습니다.
  • 고객사가 1차 분류한 태그 형태([xx-1-1-1], [xx-1-1], [xxxx-1])를 분석하여 3가지 핵심 정규식 패턴을 도출해 냈고, 이를 기준으로 카테고리, 볼륨(Vol), 단락을 도메인 식별자로 분리했습니다.
  • 예외적인 비정형 텍스트(약 2~3천 단어)는 파싱 로직을 과도하게 복잡하게 만드는 대신 클라이언트와 협의하여 수동 처리하는 유연함을 발휘했습니다.
  • 파일당 77만 자 분량의 데이터를 로컬 환경에서 건당 3분 이내에 파싱 및 적재 완료하였으며, Sequelize 트랜잭션을 적용해 실패 시 Rollback 되도록 하여 데이터 무결성을 확보했습니다.

2) 백엔드 검색 라우팅 구현 및 정렬 로직 최적화

  • Node.js 백엔드 단에서 검색어 길이를 동적으로 계산하는 분기 로직을 직접 구현했습니다. 3글자 이상은 FULLTEXT BOOLEAN MODE로, 2글자 이하의 단어는 LIKE 검색으로 라우팅되도록 처리했습니다.
  • 정확히 일치하는 단락에 최고 가중치(Relevance)를 부여하고, 인접 단락 간의 비교 로직을 추가하여 문맥 기반의 정렬(스코어링) 알고리즘을 구현했습니다.

3) 인증 설계 및 CI/CD 자동화 구축

  • Access / Refresh Token 구조를 채택하고, httpOnlysecure 옵션을 적용해 XSS 공격을 방어했습니다. 토큰에는 최소한의 Payload(ID)만 담고 사용자 정보는 별도 API로 조회하도록 설계했습니다.
  • master 브랜치 Merge 시 GitHub Actions가 트리거되어 SSH 공개키 인증 방식으로 서버에 자동 배포되도록 구성했습니다.

5. 결과 및 영향

  • 검색 성능 73% 향상 (1500ms → 400ms): 하이브리드 검색 라우팅 설계 적용 후, 검색되는 데이터의 양과 정확도가 상승했음에도 불구하고 응답 시간은 400ms 수준으로 대폭 단축되었습니다.
  • 안정적인 데이터 이관 완수: 총 5개의 대용량 교재 파일을 데이터 유실이나 서버 장애 없이 성공적으로 서비스 DB에 안착시켰습니다.
  • 운영 효율성 증대: 수동 배포 제거를 통해 백엔드 인프라 운영의 안정성을 크게 높였습니다.

6. 배운 점 및 확장 사고 (Insight)

이 프로젝트를 통해 백엔드 설계에 대한 시야를 한 단계 확장할 수 있었습니다.

  • 검색 설계에 대한 인사이트: RDBMS FULLTEXT 기반의 하이브리드 검색으로 성과를 냈으나, 현재 동일한 요구사항을 마주한다면 형태소 분석기(Nori)를 연동한 Elasticsearch 도입을 1순위로 고려할 것입니다. BM25 기반의 스코어링 방식과 검색 로그를 활용한 Relevance 튜닝을 통해 더 전문적인 검색 엔진 아키텍처를 설계해 보고 싶습니다.
  • 보안 설계 관점의 성숙: 당시 쿠키 기반 인증을 구현하며 XSS는 방어했으나 CSRF 취약점에 대한 고려는 부족했습니다. 보안 설계는 단순한 "구현"이 아니라 "공격 벡터를 가정하는 방어적 사고"가 핵심임을 깨달았습니다. 현재라면 SameSite 정책 명확화, Double Submit Cookie 방식 적용, Refresh Token Rotation 도입을 통해 더 견고한 인증 체계를 구축할 것입니다.
  • 배포 구조 및 데이터 처리 인프라 고도화: 인스턴스 서버 부하를 우려해 로컬 마이그레이션을 선택한 것은 현실적인 대응이었으나, 현재라면 Node.js 비동기 워커(Worker) 분리 또는 청크(Chunk) 단위 스트리밍 처리를 통해 서버 자체에서 대용량 데이터를 안전하게 소화하도록 설계할 것입니다. 또한, 단순 직배포 구조를 넘어 Docker 기반의 배포나 롤백 전략이 포함된 CI/CD로 파이프라인을 고도화할 것입니다.