전시 데이터 저장 구조를 v1(ES판, RDB 1:1 매핑)에서 v2(도메인 단위 통합)로 변경하며 조회 성능 개선을 목표함
v1의 거대 문서(Large Document) 및 v1의 과도한 파편화(Excessive Fragmentation) 문제 해결을 위해 MongoDB 쿼리 중심 설계 원칙 적용
v2 구조에서 발생한 쓰기 비용 증가(Increased Write Cost) 문제를 해결하기 위해 필드 단위 부분 갱신 동기화 방식 도입
증분 동기화(Incremental Synchronization)와 수동 동기화 방식을 분리하고, 발행(Publishing) 메커니즘을 추가하여 데이터 일관성(Data Consistency) 확보
본문에서는 MongoDB의 쿼리 중심 스키마 설계(Query-Driven Schema Design) 원칙을 강조하며, RDB의 정규화(Normalization) 대신 역정규화(Denormalization)를 통해 함께 읽히는 데이터를 도메인 단위로 통합하는 v2 구조를 설명함.
ES판(v0): 단일 문서에 모든 정보를 담아 거대 문서(Large Document) 문제 발생
v1: RDB 테이블을 1:1로 컬렉션화하여 과도한 파편화(Excessive Fragmentation) 및 조인(Join) 비용 증가
v2: 숙소, 객실 등 도메인 단위로 데이터를 통합하여 단일 문서 조회(Single Document Read) 최적화 및 읽기 성능(Read Performance) 향상
이러한 설계는 쓰기 비용(Write Cost) 증가라는 트레이드오프(Trade-off)를 동반하므로, 후속 동기화 방식 재설계의 필요성을 야기함.
v2 구조에서 발생한 쓰기 비용 증가(Increased Write Cost) 문제를 해결하기 위해, 변경된 필드만 선택적으로 갱신하는 필드 단위 부분 갱신(Field-Level Partial Update) 방식을 도입함.
동기화별 책임 분리: 각 동기화는 담당 필드만 갱신하여 동시성 충돌(Concurrency Conflict) 및 데이터 덮어쓰기(Data Overwriting) 방지
공용 저장 함수 활용: 데이터 변환 로직을 한 곳에서 관리하고, 각 동기화는 갱신할 필드만 지정하여 코드 중복(Code Duplication) 최소화
`$set` 및 `$unset` 연산자 활용: 변경된 필드만 명시적으로 수정하고, 비어있는 중첩 객체는 `unset`으로 제거하여 상태 명확성(State Clarity) 확보
`ordered: false` Bulk Write: 여러 건의 부분 갱신을 묶어 처리하되, 순서를 강제하지 않아 실패 격리(Failure Isolation) 및 처리 유연성 증대
객실·요금 문서처럼 여러 출처의 데이터가 혼재된 경우, 데이터 출처(Data Origin)에 따라 동기화 책임을 명확히 분리하여 동시 수정 문제(Concurrent Modification Issues)를 방지함.
객실 동기화: 객실 관련 필드(객실명, 침대, 이미지 등)만 갱신
숙소 동기화: 숙소 응답에 포함된 가격 정보만 갱신
각 동기화는 자신이 담당하는 응답에 포함된 필드만 수정하므로, 다른 출처의 데이터를 실수로 덮어쓰는 위험 없이 안전한 동시 편집(Safe Concurrent Editing)이 가능함.
이는 필드 단위 갱신(Field-Level Update)의 핵심 이점으로, 통합된 문서 구조의 이점을 유지하면서도 쓰기 작업의 안정성을 높이는 데 기여함.
v2 시스템은 증분 동기화(Incremental Synchronization)와 수동 동기화(Manual Synchronization) 트리거를 명확히 분리하여 운영 효율성을 높임.
증분 동기화: 외부 변경 이벤트 발생 시 해당 건만 처리하는 주요 운영 경로로 활용
수동 동기화: 초기 데이터 적재, 정합성 복구, 대량 보정 등 필요 시 운영자가 직접 트리거하며, 대상 컬렉션 및 처리 건수(Chunk Size)를 선택하여 부하를 분산하고 운영 부담 경감
이러한 분리는 데이터 정합성(Data Integrity) 유지와 운영 편의성(Operational Convenience) 증대에 기여하며, 특히 대규모 데이터셋 처리 시 리소스 부하(Resource Load)를 평탄화하는 데 효과적임.
데이터 저장 후 변경 이벤트 발행(Change Event Publishing) 메커니즘을 추가하여, Redis 캐시와 같은 하위 시스템의 데이터 최신성(Data Freshness)을 보장함.
발행 메시지: 변경된 키 목록, 도메인 종류, 변경 유형(생성/수정/삭제) 포함
비동기 처리: 발행 실패가 데이터 저장 작업에 영향을 주지 않도록 논블로킹(Non-blocking) 방식으로 처리하고, 실패 시 로깅 및 알림으로 관리
구독자(Subscriber) 역할: 변경 이벤트를 구독하여 Redis 캐시를 최신 상태로 유지함으로써, 읽기 성능 최적화(Read Performance Optimization)의 이점을 유지함.
이는 데이터 저장과 소비 간의 최종 일관성(Eventual Consistency) 모델을 구현하는 핵심 요소임.
기존 v1 시스템을 운영하면서 v2 시스템을 안전하게 전환하기 위해 병행 운영(Parallel Operation) 및 점진적 비중 확대(Gradual Weight Increase) 전략을 채택함.
이중 쓰기(Dual Write): 증분 이벤트 발생 시 v1과 v2 문서를 동시에 갱신하여 데이터 정합성 유지
수동 동기화 활용: 신규 컬렉션 초기화 및 검증 과정에서 특정 부분만 선택적으로 동기화하여 v2 데이터 검증 및 보완
이러한 단계적 접근 방식은 서비스 중단(Service Interruption) 없이 v2 시스템의 안정성을 확보하고, 트래픽 비중을 점진적으로 늘려가며 리스크를 최소화하는 데 기여함.