당근 / flink-cdc

2 개의 포스트

daangn

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

당근 데이터 가치화 팀은 서비스 성장에 따른 데이터 규모 증가로 기존 MongoDB 전체 덤프 방식이 유발하던 DB 부하와 데이터 적재 지연 문제를 해결하기 위해 Flink CDC를 도입했습니다. 이를 통해 전체 데이터를 매번 조회하지 않고 변경된 로그만 캡처하여 BigQuery로 적재함으로써 DB CPU 부하를 60% 이하로 안정화하고, 2시간 이내 데이터 전달이라는 서비스 수준 목표(SLO)를 달성했습니다. 결과적으로 운영 효율성과 데이터 분석의 실시간성을 동시에 확보하는 파이프라인을 구축할 수 있었습니다. **기술 스택 선정: 왜 Flink CDC인가?** * **MongoDB Change Stream 네이티브 지원**: 별도의 커넥터 개발 없이 MongoDB의 고수준 변경 이벤트 API인 Change Stream을 안정적으로 구독할 수 있으며, resume token과 Flink의 체크포인트 기능을 연동해 장애 시에도 정확한 시점부터 재시작이 가능합니다. * **Exactly-Once 처리 보장**: 분산 파일 시스템에 상태를 주기적으로 저장하는 체크포인트 전략을 통해 장애가 발생하더라도 데이터 중복이나 누락 없이 '정확히 한 번' 처리를 보장합니다. * **통합 파이프라인 구축**: 변경 데이터 추출(CDC)부터 데이터 정제, 변환, BigQuery로의 적재(Sink)까지 하나의 Job 안에서 End-to-End로 처리할 수 있어 운영 복잡도가 낮습니다. * **병렬 처리 기반의 확장성**: TaskManager를 늘려 처리량을 선형적으로 확장할 수 있어, 데이터 이벤트가 폭증하는 상황에서도 유연하게 대응할 수 있습니다. **CDC 기반 아키텍처 및 데이터 흐름** * **Change Stream 활용**: MongoDB의 모든 쓰기 연산을 기록하는 Oplog를 Change Stream을 통해 실시간으로 구독하여 insert, update, delete 이벤트를 수신합니다. * **단계별 배치 파이프라인**: 2시간 이내의 SLO 충족과 운영 안정성을 위해 실시간 스트리밍 대신 매시간(hourly) 배치 방식을 채택했습니다. * **Schema Evolution**: 스키마 저장소와 BigQuery 테이블을 비교하여 변경된 필드를 자동으로 반영합니다. * **Extract & Merge**: 최근 변경 이벤트에서 중복을 제거하고 추출하여 JSON 형태의 Raw 테이블에 병합합니다. * **Materialize**: 최종적으로 스키마를 적용해 사용자가 분석하기 쉬운 테이블 형태로 구체화합니다. * **배치 방식의 이점**: 시간 윈도우를 통해 지연된 이벤트를 안정적으로 회수할 수 있고, 장애 발생 시 실패 구간을 명확히 정의해 재처리(Backfill)하기가 용이합니다. **실용적인 결론** 대규모 트래픽이 발생하는 서비스 환경에서 운영 데이터베이스의 부하를 최소화하면서 분석용 데이터를 확보하려면 CDC 도입이 필수적입니다. 특히 MongoDB와 같이 스키마가 유연한 NoSQL 데이터를 BigQuery와 같은 정형 데이터 저장소로 옮길 때는, Flink CDC와 같은 통합 처리 엔진을 활용해 변환 로직과 확장성을 동시에 확보하는 것이 운영 효율 측면에서 매우 유리합니다. 실시간성이 극도로 중요하지 않다면 배치 단계를 결합해 데이터 정합성과 멱등성을 보장하는 구조를 고려해볼 수 있습니다.

daangn

매번 다 퍼올 필요 없잖아? 당근의 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에 맞춰 배치와 스트리밍 중 적절한 주기를 선택하는 것이 운영 안정성 측면에서 권장됩니다.