pile·
DB / 데이터·여기어때 (GC컴퍼니)여기어때 (GC컴퍼니)·

데이터 통합— MongoDB 원칙으로 document를 통합하고 동기화를 재설계하다 (3/3)

여기어때 전시개발팀은 ES 단일 대문서 → MongoDB v1 RDB 1:1 파편화 → v2 도메인 단위 통합이라는 세 차례 구조 전환을 거쳐 전체 동기화 시간을 약 1시간에서 10분으로 단축했다. 이 글은 3부작의 마지막으로, v2 통합 문서 구조에 맞춰 "$set/$unset 필드 단위 부분 갱신 + 이벤트 발행" 기반 동기화를 어떻게 재설계했는지 구체적인 MongoDB 패턴과 함께 설명한다.

핵심 포인트
  • MongoDB 원칙 "Model your schema according to your application's queries"를 따라 RDB 1:1 컬렉션(v1)에서 도메인 단위 통합(v2)으로 전환하여 동기화 시간 1시간→10분 단축
  • 역정규화(Read 최적화)의 대가는 Write 비용 증가 — `$set/$unset` 부분 갱신 + `ordered:false bulkWrite`가 필수 짝
  • 같은 문서를 출처가 다른 두 동기화(객실/숙소)가 각자 담당 필드만 갱신해 서로 간섭 없이 공유
  • 변경 이벤트 논블로킹 발행으로 Redis 캐시를 최신화하는 "저장 → 알림" 패턴 추가
  • v1·v2 병행 운영으로 기존 경로 유지하며 비중을 단계적으로 이행
상세 정리
  • ES판: 한 숙소 모든 정보를 문서 하나에 담아 수십 MB 거대 문서 → 직렬화/전송 느림
  • v1: RDB 테이블 구조를 MongoDB에 1:1 매핑해 수십 개 컬렉션 → 조회마다 aggregation join 비용 (MongoDB 공식 안티패턴)
  • v2: 함께 읽히는 데이터를 도메인 단위로 묶어 소수 컬렉션, 16MB 제한 고려해 도메인별 문서 분리
  • 공용 저장 함수: 변환 로직 중앙화 → 각 동기화는 "갱신할 필드 목록"만 전달
  • 부분 갱신 패턴: `$set: {"rooms.$[room].price": nextPrice}` + 부모 객체 비면 `$unset`으로 명시적 제거
  • `bulkWrite(ops, {ordered: false})`: N건 한 번에 묶어 처리, 한 건 실패해도 나머지 처리 계속
  • 증분 동기화(이벤트 기반)와 수동 동기화(API 트리거, 청크 단위) 명확히 분리; 수동 동기화는 대상 도메인 선택 가능
  • 변경 이벤트 메시지: 변경 키 목록, 도메인 종류, 변경 유형(생성·수정/삭제) 포함
  • 발행 실패는 동기화를 막지 않음(논블로킹), 로깅·알림으로만 처리
왜 읽나MongoDB 역정규화 설계 도입 시 불가피한 쓰기 비용을 필드 단위 부분 갱신과 이벤트 발행 패턴으로 제어하는 실전 설계를 배울 수 있다.
여기어때 (GC컴퍼니)
여기어때 (GC컴퍼니) 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. DB / 데이터·pinterest-engPinterest Engineering·

    Pinterest 차세대 DB 수집 프레임워크의 자동화된 스키마 진화

    Pinterest의 CDC 기반 DB 수집 파이프라인은 MySQL에서 Kafka, Flink, Spark, Iceberg를 거치는 다층 구조다. 스키마 변경이 생기면 모든 계층을 동시에 업데이트해야 해 드리프트, 배포 실패, 데이터 불일치가 반복됐다. Pinterest 엔지니어링 팀은 이를 해결하기 위해 가산적 변경만 자동화하는 스키마 진화 프레임워크를 구축하고, PR 기반 롤아웃과 SLA 기반 일관성 모델을 도입했다.

    #data-pipeline#apache-flink#cdc+2