change-data-capture

3 개의 포스트

Pinterest의 차세대 DB 인 (새 탭에서 열림)

Pinterest는 기존의 파편화된 배치 기반 DB 적재 시스템을 개선하기 위해 Iceberg와 CDC(Change Data Capture) 기술을 결합한 통합 프레임워크를 구축했습니다. 이 시스템은 데이터 지연 시간을 24시간 이상에서 수 분 단위로 단축하고, 변경된 데이터만 처리하는 방식으로 인프라 비용을 획기적으로 절감했습니다. 이를 통해 분석, 머신러닝, 규정 준수 등 현대적인 데이터 요구사항에 기민하게 대응할 수 있는 고성능 데이터 생태계를 마련했습니다. ### 통합 CDC 프레임워크의 계층 구조 * **CDC 레이어**: Debezium 및 TiCDC를 활용해 MySQL, TiDB, KVStore의 변경 사항을 1초 미만의 지연 시간으로 포착하여 Kafka에 기록합니다. * **스트리밍 레이어**: Flink 작업이 Kafka의 이벤트를 실시간으로 처리하여 S3에 위치한 'CDC Iceberg 테이블'에 추가 전용(Append-only) 방식으로 저장합니다. * **배치 레이어**: Spark 작업이 주기적으로(15~60분) CDC 테이블의 최신 변경 사항을 읽어 `Merge Into` 구문을 통해 최종 'Base Iceberg 테이블'에 업서트(Upsert)를 수행합니다. * **부트스트랩 및 유지보수**: 초기 데이터 로드를 위한 전용 파이프라인과 소형 파일 압축(Compaction) 및 스냅샷 만료 관리를 위한 유지보수 작업을 포함합니다. ### CDC 테이블과 베이스 테이블의 이원화 관리 * **CDC 테이블**: 모든 변경 이력을 담은 시계열 원장으로, 5분 미만의 지연 시간을 유지하며 원천 데이터의 변경 로그를 보존합니다. * **베이스 테이블**: 온라인 DB의 현재 상태를 그대로 반영하는 스냅샷 테이블입니다. CDC 테이블로부터 최신 레코드를 추출하여 정합성을 맞춥니다. * **동기화 로직**: `ROW_NUMBER()` 함수를 활용해 기본 키(PK)별로 가장 최신 업데이트(최근 타임스탬프 및 GTID 기준)를 식별한 후, 삭제 유형은 제거하고 나머지는 업데이트 또는 삽입합니다. ### 성능 및 비용 최적화 전략 * **Merge-on-Read (MOR) 방식 채택**: Copy-on-Write(COW) 방식은 업데이트 시 대규모 파일을 다시 작성해야 하므로 스토리지와 계산 비용이 높습니다. Pinterest는 비용 효율성을 극대화하기 위해 MOR 방식을 표준 전략으로 선택했습니다. * **기본 키 해시 버킷팅(Bucketing)**: 베이스 테이블을 PK의 해시값(예: `bucket(100, id)`)으로 파티셔닝하여 Spark가 업서트 작업을 병렬로 효율적으로 처리할 수 있도록 설계했습니다. * **증분 처리 효율성**: 매일 전체 테이블을 덤프하던 방식에서 변경된 데이터(통상 5% 미만)만 처리하는 방식으로 전환하여 연산 리소스 낭비를 차단했습니다. 방대한 양의 데이터베이스를 데이터 레이크로 통합할 때는 Iceberg의 `Merge Into` 기능을 활용한 증분 업데이트가 필수적입니다. 특히 읽기 성능과 쓰기 비용 사이의 균형을 위해 MOR 전략을 사용하고, 쓰기 병목을 해소하기 위해 기본 키 기반의 버킷팅을 적용하는 것이 실무적으로 매우 효과적인 접근임을 보여줍니다.

매번 다 퍼올 필요 없잖아? 당근의 MongoDB CDC 구축기 (새 탭에서 열림)

당근은 서비스 성장에 따른 데이터 규모 확대와 이로 인한 MongoDB 부하 문제를 해결하기 위해 기존의 전체 덤프 방식 대신 Flink CDC를 도입했습니다. 이를 통해 DB 부하를 60% 이하로 안정화하면서도 2시간 이내 데이터 전달이라는 SLO(Service Level Objective)를 충족하는 성과를 거두었습니다. 결과적으로 확장성 있는 파이프라인을 구축하여 서비스 안정성과 데이터 분석 효율성을 동시에 확보했습니다. **기존 방식의 한계와 CDC 도입 배경** * **성능적 한계:** 기존에는 Spark Connector를 사용해 전체 데이터를 덤프했으나, 데이터가 늘어날수록 DB CPU 사용률이 급증(Spike)하고 적재 시간이 길어지는 문제가 발생했습니다. * **안정성 문제:** 2시간 내 데이터 적재라는 목표를 맞추려면 DB 부하가 너무 커지고, 부하를 줄이면 적재 시간이 지연되는 트레이드오프 상황에 직면했습니다. * **CDC의 필요성:** `updated_at` 같은 특정 필드에 의존하는 증분 적재 방식은 스키마 변경이나 누락에 취약하므로, DB의 변경 로그(Oplog)를 직접 읽어 변경분을 추적하는 CDC 방식이 최적의 대안으로 선정되었습니다. **Flink CDC를 최종 선택한 기술적 이유** * **Change Stream 네이티브 지원:** MongoDB의 Change Stream 기능을 활용해 변경 로그를 안정적으로 읽어오며, resume token과 체크포인트를 연동하여 장애 발생 시에도 중단된 지점부터 정확히 재개할 수 있습니다. * **정확히 한 번(Exactly-Once) 보장:** 강력한 체크포인트 메커니즘을 통해 상태를 외부 스토리지(GCS/S3 등)에 보존하므로 데이터 중복이나 누락 없는 처리가 가능합니다. * **통합 파이프라인 구성:** CDC 데이터 추출부터 변환(Transform), 적재(Sink)까지 하나의 Job 내에서 엔드투엔드(End-to-End)로 처리할 수 있어 운영 복잡도가 낮습니다. * **병렬 처리 기반의 확장성:** TaskManager를 늘림으로써 처리량을 선형적으로 확장할 수 있어, 이벤트가 급증하는 상황에도 유연하게 대응할 수 있습니다. **CDC 기반 데이터 파이프라인 아키텍처** * **실시간 구독 및 적재:** MongoDB에서 발생하는 모든 변경 이벤트(insert, update, delete)를 Flink CDC가 실시간으로 수집하여 BigQuery로 전송합니다. * **효율적인 배치 전략:** 실시간 스트리밍 대신 1시간 단위(Hourly) 배치 방식을 채택하여 시스템 복잡도를 낮추고, 장애 시 재처리의 용이성과 멱등성을 확보했습니다. * **단계별 후처리 프로세스:** 1. **Schema Evolution:** 스키마 저장소와 비교하여 BigQuery 테이블의 필드를 자동 업데이트합니다. 2. **Extract & Merge:** 최신 변경 이벤트를 추출해 중복을 제거하고 원본 형태의 Raw 테이블에 병합합니다. 3. **Materialize:** 최종적으로 스키마를 적용해 분석에 최적화된 테이블로 구체화합니다. 대규모 트래픽 환경에서 운영 DB의 부하를 최소화하면서 데이터 가용성을 높이려면, 무조건적인 전체 조회보다는 CDC를 통한 변경분 추적 방식이 필수적입니다. 특히 데이터 모델 변환이 잦은 NoSQL 환경이라면 Flink CDC와 같은 통합 도구를 활용해 파이프라인을 단순화하고, 서비스의 SLO에 맞춰 배치와 스트리밍 중 적절한 주기를 선택하는 것이 운영 안정성 측면에서 권장됩니다.

며칠의 지연 시간에서 실 (새 탭에서 열림)

피그마(Figma)는 급격한 사용자 증가와 데이터 볼륨 확대에 대응하기 위해 기존의 배치 기반 동기화 시스템을 실시간 증분 동기화(Incremental Synchronization) 파이프라인으로 전면 재구축했습니다. 과거 수일이 소요되던 데이터 동기화 지연 시간을 근실시간(Near Real-time) 수준으로 단축함으로써 데이터 분석의 신속성과 정확성을 확보했습니다. 이 과정에서 상용 솔루션 대신 자체 인프라에 최적화된 기술 스택을 선택하여 비용 절감과 확장성이라는 두 마리 토끼를 잡는 데 성공했습니다. **기존 배치 동기화 방식의 한계와 비용 문제** * 2020년에 설계된 초기 시스템은 매일 전체 테이블을 `SELECT *` 쿼리로 조회하여 S3에 업로드하고 Snowflake로 가져오는 단순한 구조였습니다. * 데이터 규모가 커짐에 따라 동기화 작업이 6시간에서 길게는 수일까지 지연되었으며, 이를 처리하기 위해 고가의 데이터베이스 복제본을 유지하는 데 매년 수백만 달러의 비용이 발생했습니다. * 동기화 지연은 전사 KPI 분석 및 비즈니스 의사결정을 방해하는 핵심 병목 구간이 되었습니다. **상용 솔루션 대신 자체 구축을 선택한 이유** * **유연성:** Amazon RDS와 같은 특정 클라우드 벤더의 API를 활용해 복제본 유지 관리 오버헤드 없이 직접 스냅샷을 생성하는 등 인프라 최적화가 필요했습니다. * **비용 효율성:** 대규모 데이터 환경에서 상용 솔루션을 사용할 경우 자체 구축 대비 약 5~10배 이상의 비용이 발생할 것으로 예상되었습니다. * **확장성:** 피그마의 지속적인 성장에 맞춰 빠르게 혁신하고 제어할 수 있는 맞춤형 파이프라인이 필요했습니다. **증분 동기화를 위한 기술적 아키텍처** * **스냅샷 및 데이터 적재:** Amazon RDS의 스냅샷 내보내기 기능을 사용해 S3로 초기 데이터를 복사하고, Snowflake의 `COPY INTO` 문을 통해 베이스 테이블에 로드합니다. * **CDC(Change Data Capture) 스트리밍:** Kafka Connect를 활용해 Postgres의 변경 로그를 실시간으로 캡처하고, Amazon MSK를 거쳐 Snowflake의 CDC 테이블로 스트리밍합니다. * **증분 병합(Merge):** Snowflake의 저장 프로시저(Stored Procedure)와 태스크(Task) 기능을 이용해 베이스 테이블과 CDC 데이터를 주기적으로 병합하는 맞춤형 `MERGE` 로직을 구현했습니다. **데이터 무결성을 위한 워크플로우 설계** * **부트스트랩(Bootstrap):** 새로운 테이블을 파이프라인에 추가할 때 스키마 진화에 대응할 수 있도록 아티팩트를 버전화하고, 원자적 뷰(View) 업데이트를 통해 서비스 중단 없는 전환을 지원합니다. * **검증(Validation):** 부분적 실패, 설정 오류, 소스 데이터의 이상 현상으로 인한 데이터 부패를 방지하기 위해 파이프라인 전 과정에서 데이터의 정확성과 일관성을 검증하는 프로세스를 통합했습니다. 데이터 파이프라인의 성능 한계에 직면한 조직은 단순히 컴퓨팅 파워를 늘리기보다, 전체 데이터를 옮기지 않는 '증분 동기화'와 자사 환경에 최적화된 CDC 기술 스택을 도입함으로써 비용과 성능 문제를 근본적으로 해결할 수 있습니다. 특히 대규모 환경에서는 벤더 종속성을 탈피한 자체 아키텍처 설계가 장기적인 확장성 면에서 더 유리할 수 있습니다.