apache-kafka

9 개의 포스트

2조 토큰을 카테고리 분류에 쓰면서 알게된 것들 (새 탭에서 열림)

당근 Taxonomy 팀은 방대한 중고거래 게시글과 서비스 데이터를 효율적으로 분류하기 위해 LLM 기반의 자동화 파이프라인인 'Taxonomy Management System'을 구축했습니다. 이 시스템은 Dataflow를 통한 고병렬 추론과 LLM as a Judge 방식의 평가 체계를 결합하여, 사람이 직접 수행하던 카테고리 관리와 라벨링 비용을 획기적으로 줄이면서도 1만 개 이상의 정교한 카테고리 체계를 안정적으로 운영하고 있습니다. 2조 토큰에 달하는 대규모 데이터를 처리하며 얻은 노하우를 통해, 단순 분류를 넘어 서비스 전반의 공통 데이터 언어를 구축하는 성과를 거두었습니다. **택소노미의 중요성과 자동화의 필요성** * 택소노미는 검색, 추천, 광고 등 서비스 전반에서 데이터를 통일된 방식으로 다루기 위한 계층적 카테고리 체계이자 공통 언어입니다. * 기존의 수동 분류 방식은 도메인 전문가의 리소스가 과도하게 소요되고, 사용자가 입력한 데이터만으로는 정밀한 분류(3-depth 이상)가 어렵다는 한계가 있었습니다. * LLM을 활용해 사용자가 입력하지 않은 세부 카테고리와 속성(브랜드, 색상, 재질 등)을 자동으로 추출하여 데이터의 표현력을 높였습니다. **Dataflow와 BigQuery 중심의 파이프라인 설계** * 초 단위의 응답 시간이 걸리는 LLM 추론을 대규모 배치 및 스트림으로 처리하기 위해 Apache Beam 기반의 Google Cloud Dataflow를 채택하여 병렬 처리 성능을 확보했습니다. * 추론 결과의 원천 데이터(Source of Truth)를 BigQuery에 적재하여 분석과 학습에 즉시 활용하고, 실시간 서비스가 필요한 경우 Kafka를 통해 피처 플랫폼으로 전달합니다. * 택소노미 정의, 파이프라인 설정, 모델 옵션(Gemini, GPT, Claude 등)을 YAML 파일로 관리하여 코드 수정 없이 유연하게 시스템을 운영할 수 있도록 설계했습니다. **LLM을 이용한 택소노미 생성 및 확장 전략** * 기존 1,400개 수준의 카테고리를 LLM 기반의 리서치와 실데이터 분석을 통해 6-depth, 10,000개 이상의 정교한 체계로 확장했습니다. * 신규 카테고리 후보가 발생하면 기존 데이터 할당 테스트와 회귀 평가(Regression)를 거쳐 품질이 검증된 경우에만 정식 택소노미로 편입시킵니다. * 다국어 지원 시 일관성을 유지하기 위해 DFS(깊이 우선 탐색) 방식으로 상위 카테고리의 번역 문맥을 하위 단계 LLM에게 전달하는 방식을 사용했습니다. **추론 전략 최적화와 품질 관리(LLM as a Judge)** * 단일 단계(Single Shot), 계층적(Hierarchical), 토너먼트(Two-stage) 방식 등 택소노미 규모에 맞는 다양한 추론 전략을 모듈화하여 교체 가능하게 구현했습니다. * 분류 결과의 정확도를 측정하기 위해 여러 모델이 투표하여 정답(Ground Truth)을 정하는 'LLM as a Judge' 방식을 도입했습니다. * 카테고리 정확도(Accuracy)뿐만 아니라 다중 라벨인 속성 데이터에 대해서는 정밀도(Precision)와 재현율(Recall) 지표를 상시 모니터링하여 프롬프트와 모델 변경의 효과를 즉각 검증합니다. **실용적인 결론 및 추천** 대규모 서비스에서 카테고리 분류를 자동화하려는 팀은 처음부터 완벽한 모델을 찾기보다, **다양한 LLM 전략을 실험할 수 있는 모듈형 파이프라인**과 **자동화된 평가 체계(LLM as a Judge)**를 먼저 구축하는 것이 중요합니다. 특히 데이터 소스가 다양해질 것에 대비해 이벤트 스트림과 배치 처리를 동시에 지원하는 인프라를 선택하고, 분류 결과가 실제 서비스 피처로 흐를 수 있는 파이프라인 구조를 설계할 것을 권장합니다.

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 전략을 사용하고, 쓰기 병목을 해소하기 위해 기본 키 기반의 버킷팅을 적용하는 것이 실무적으로 매우 효과적인 접근임을 보여줍니다.

비용, 성능, 안정성을 목표로 한 지능형 로그 파이프라인 도입 (새 탭에서 열림)

네이버의 통합 데이터 플랫폼 AIDA 내 로그 수집 시스템인 'Logiss'는 대규모 로그 파이프라인을 운영하며 겪었던 무중단 배포의 한계, 리소스 낭비, 로그 중요도 미분류 문제를 해결하기 위해 지능형 파이프라인을 도입했습니다. 핵심은 Storm의 멀티 토폴로지 구성을 통한 블루-그린 배포 구현과 실시간 트래픽 상태에 따라 처리 속도를 동적으로 조절하는 지능형 제어 알고리즘의 적용입니다. 이를 통해 서비스 중단 없는 배포는 물론, 인프라 비용을 약 40% 절감하고 장애 시 핵심 로그를 우선 처리하는 안정성까지 확보하며 성능과 비용의 최적점을 찾아냈습니다. **멀티 토폴로지와 블루-그린 배포를 통한 무중단 운영** * 기존 Traffic-Controller는 단일 토폴로지 구조로 인해 배포 시마다 데이터 처리가 3~8분간 중단되는 문제가 있었으나, 이를 해결하기 위해 멀티 토폴로지 기반의 블루-그린 배포 방식을 도입했습니다. * Storm 2.x의 `assign` 방식 대신 Kafka의 컨슈머 그룹 관리 기능을 활용하는 `subscribe` 방식으로 내부 로직을 커스텀 변경하여, 여러 토폴로지가 동일 파티션을 중복 소비하지 않도록 개선했습니다. * 이를 통해 트래픽이 몰리는 낮 시간대에도 중단 없이 안전하게 신규 기능을 배포하고 점진적인 트래픽 전환이 가능해졌습니다. **지능형 트래픽 제어를 통한 리소스 최적화** * 낮과 밤의 트래픽 차이가 5배 이상 발생하는 환경에서 피크 타임 기준으로 장비를 고정 할당하던 비효율을 제거하기 위해 '지능형 속도 제어' 알고리즘을 도입했습니다. * Kafka의 랙(lag) 발생량과 백엔드 시스템(OpenSearch 등)의 CPU 부하 상태를 실시간으로 감시하여, 시스템이 여유로울 때는 로그 처리 속도를 자동으로 높여 적체를 빠르게 해소합니다. * 유동적인 속도 조절 덕분에 기존 대비 투입 장비 리소스를 약 40% 절감하는 성과를 거두었으며, 갑작스러운 트래픽 유입에도 유연하게 대응할 수 있게 되었습니다. **로그 중요도 기반의 우선순위 처리** * 모든 로그를 동일한 속도로 처리하던 방식에서 벗어나, 비상 상황 발생 시 서비스 핵심 로그가 먼저 처리될 수 있도록 우선순위(High, Medium, Low) 개념을 도입했습니다. * 트래픽 지연이 발생하면 중요도가 낮은 로그의 처리 속도는 제한하고, 사업 및 서비스 운영에 필수적인 핵심 로그는 지연 없이 전송되도록 파이프라인 가용성을 확보했습니다. **저장소별 차등 샘플링을 통한 비용 절감** * 실시간 검색을 위한 OpenSearch와 장기 보관을 위한 랜딩 존(Landing Zone)에 데이터를 전송할 때, 각 저장소의 목적에 맞게 샘플링 비율을 다르게 설정할 수 있는 기능을 구현했습니다. * 모든 데이터를 무조건 100% 저장하는 대신, 분석 목적에 따라 일부 샘플링만으로 충분한 로그는 저장량을 줄여 인덱싱 부하를 낮추고 스토리지 비용을 효율적으로 관리할 수 있게 되었습니다. 대규모 로그 파이프라인 운영에서 비용 효율과 안정성은 상충하기 쉬운 가치이지만, 시스템의 상태를 실시간으로 파악하고 제어하는 '지능형' 로직을 통해 두 마리 토끼를 모두 잡을 수 있습니다. 특히 스트리밍 처리 프레임워크의 제약 사항을 직접 커스텀하여 비즈니스 요구사항에 맞춘 최적화 사례는 유사한 데이터 플랫폼을 운영하는 기술진에게 실무적인 통찰을 제공합니다.

고객은 절대 기다려주지 않는다: 빠른 데이터 서빙으로 고객 만족도를 수직 상승 시키는 법 (새 탭에서 열림)

토스페이먼츠는 가파른 성장세에 따른 데이터 조회 부하를 해결하기 위해 CQRS 아키텍처를 도입하고 Apache Druid를 중심으로 한 데이터 서빙 환경을 구축했습니다. 초기에는 Elasticsearch와 Druid를 결합하여 대규모 시계열 데이터의 실시간 집계와 검색 성능을 확보했으며, 이를 통해 비용 효율성과 시스템 안정성을 동시에 달성했습니다. 현재는 Druid의 조인 제약과 멱등성 문제를 해결하기 위해 StarRocks를 도입하며, 도메인 간 결합이 자유로운 통합 원장 시스템으로 진화하고 있습니다. ### CQRS와 Apache Druid 도입 배경 * **MSA 전환과 DB 분리:** 서비스 규모가 커지며 모놀리식에서 MSA로 전환했으나, DB가 분산되면서 도메인 간 조인이나 통합 조회가 어려워지는 문제가 발생했습니다. * **명령과 조회의 분리:** 읽기 전용 저장소로 Apache Druid를 선택하여 원장 DB(MySQL)의 부하를 줄이고, 수십억 건의 데이터를 저지연으로 조회하는 CQRS 구조를 설계했습니다. * **Druid의 기술적 이점:** 시계열 데이터 최적화, SQL 지원을 통한 낮은 러닝 커브, 모든 컬럼의 비트맵 인덱스(Bitmap Index)화, 그리고 클라우드 네이티브 구조를 통한 비용 효율성을 고려했습니다. ### 데이터 가공 및 메시지 발행 방식 * **CDC 대신 메시지 발행 선택:** 데이터팀이 도메인 로직을 직접 소유해야 하는 CDC 방식 대신, 각 도메인 팀에서 완성된 데이터를 발행하는 방식을 채택하여 시스템 의존성을 Kafka로 단순화했습니다. * **역정규화 테이블 구성:** 복잡한 수단별 원장 데이터를 조회 친화적인 역정규화 테이블로 변환하여 적재했으며, JSON 필드 단위까지 비트맵 인덱스가 생성되어 효율적인 질의가 가능해졌습니다. ### AWS 환경에서의 비용 및 성능 최적화 * **컴퓨팅과 스토리지 분리:** 고가의 네트워크 스토리지(EBS) 대신 S3를 영구 저장소로 활용하고, 쿼리 수행 시에는 로컬 SSD를 사용하여 성능을 9배 이상 향상했습니다. * **스팟 인스턴스 활용:** 데이터가 S3에 안전하게 보관되는 특성을 이용해 개발/테스트 환경에서 스팟 인스턴스를 적극적으로 사용하여 월 5,000만 원 이상의 클라우드 비용을 절감했습니다. * **고가용성 확보:** 네트워크 스토리지 의존성을 제거함으로써 가용 영역(AZ) 간 분산 배치가 유연해져 시스템의 안정성을 높였습니다. ### Druid 운영의 기술적 도전과 극복 * **파편화 및 멱등성 문제:** 데이터가 시점별로 분산되는 파편화 현상을 해결하기 위해 60초 주기 탐지 프로세스와 자동 컴팩션(Compaction)을 도입했습니다. * **Rollup을 통한 성능 극대화:** 동일 차원의 데이터를 자동 집계하여 저장하는 Rollup 기능을 적용해, 수십 초 걸리던 집계 쿼리 응답 속도를 0.5~1초 내외로 99% 이상 개선했습니다. * **ES 하이브리드 아키텍처:** 단일 ID 기반의 고속 검색은 Elasticsearch가 담당하고, 필터링된 결과의 대규모 집계는 Druid가 처리하도록 역할을 분담해 검색 성능을 안정화했습니다. ### StarRocks 도입을 통한 통합 원장 구축 * **조인 및 멱등성 한계 극복:** Druid의 제한적인 조인 기능과 멱등성 처리의 어려움을 해결하기 위해 StarRocks를 새롭게 도입했습니다. * **도메인 간 데이터 결합:** 결제부터 매입, 정산까지 이르는 전체 라이프사이클을 한눈에 볼 수 있는 통합 원장을 구현하여 비즈니스 요구사항에 유연하게 대응하고 있습니다. **결론적으로** 대규모 트래픽 환경에서는 단순한 DB 분리를 넘어 검색(ES), 시계열 집계(Druid), 그리고 복잡한 조인과 멱등성 보장(StarRocks)이라는 각 도구의 장점을 살린 하이브리드 아키텍처 설계가 필수적입니다. 특히 스토리지와 컴퓨팅을 분리한 구조는 비용 절감뿐만 아니라 운영의 유연성을 확보하는 핵심 전략이 됩니다.

6개월 만에 연간 수십조를 처리하는 DB CDC 복제 도구 무중단/무장애 교체하기 (새 탭에서 열림)

네이버페이는 차세대 아키텍처 개편 프로젝트인 'Plasma'의 최종 단계로, 연간 수십조 원의 거래 데이터를 처리하는 DB CDC 복제 도구인 'ergate'를 성공적으로 개발하여 무중단 교체했습니다. 기존의 복제 도구(mig-data)가 가진 유지보수의 어려움과 스키마 변경 시의 제약 사항을 해결하기 위해 Apache Flink와 Spring Framework를 조합한 새로운 구조를 도입했으며, 이를 통해 확장성과 성능을 동시에 확보했습니다. 결과적으로 백엔드 개발자가 직접 운영 가능한 내재화된 시스템을 구축하고, 대규모 트래픽 환경에서도 1초 이내의 복제 지연 시간과 강력한 데이터 정합성을 보장하게 되었습니다. ### 레거시 복제 도구의 한계와 교체 배경 * **유지보수 및 내재화 필요성:** 기존 도구인 `mig-data`는 DB 코어 개발 경험이 있는 인원이 순수 Java로 작성하여 일반 백엔드 개발자가 유지보수하거나 기능을 확장하기에 진입 장벽이 높았습니다. * **엄격한 복제 제약:** 양방향 복제를 지원하기 위해 설계된 로직 탓에 단일 레코드의 복제 실패가 전체 복제 지연으로 이어졌으며, 데이터 무결성 확인을 위한 복잡한 제약이 존재했습니다. * **스키마 변경의 경직성:** 반드시 Target DB에 칼럼을 먼저 추가해야 하는 순서 의존성이 있어, 작업 순서가 어긋날 경우 복제가 중단되는 장애가 빈번했습니다. * **복구 프로세스의 부재:** 장애 발생 시 복구를 수행할 수 있는 인원과 방법이 제한적이어서 운영 효율성이 낮았습니다. ### Apache Flink와 Spring을 결합한 기술 아키텍처 * **프레임워크 선정:** 저지연·대용량 처리에 최적화된 **Apache Flink(Java 17)**를 복제 및 검증 엔진으로 채택하고, 복잡한 비즈니스 로직과 복구 프로세스는 익숙한 **Spring Framework(Kotlin)**로 이원화하여 구현했습니다. * **Kubernetes 세션 모드 활용:** 12개에 달하는 복제 및 검증 Job을 효율적으로 관리하기 위해 세션 모드를 선택했습니다. 이를 통해 하나의 Job Manager UI에서 모든 상태를 모니터링하고 배포 시간을 단축했습니다. * **Kafka 기반 비동기 처리:** nBase-T의 binlog를 읽어 Kafka로 발행하는 `nbase-cdc`를 소스로 활용하여 데이터 유실 없는 파이프라인을 구축했습니다. ### 데이터 정합성을 위한 검증 및 복구 시스템 * **지연 컨슈밍 검증(Verifier):** 복제 토픽을 2분 정도 지연하여 읽어 들이는 방식으로 Target DB에 데이터가 반영될 시간을 확보한 뒤 정합성을 체크합니다. * **2단계 검증 로직:** 1차 검증 실패 시, 실시간 변경으로 인한 오탐인지 확인하기 위해 Source DB를 직접 재조회하여 Target과 비교하는 보완 로직을 수행합니다. * **자동화된 복구 흐름:** 일시적인 오류는 5분 후 자동으로 복구하는 '순단 자동 복구'와 배치 기반의 '장애 자동 복구', 그리고 관리자 UI를 통한 '수동 복구' 체계를 갖추어 데이터 불일치 제로를 지향합니다. ### DDL 독립성 및 성능 개선 결과 * **스키마 캐싱 전략:** `SqlParameterSource`와 캐싱된 쿼리를 이용해 Source와 Target의 칼럼 추가 순서에 상관없이 복제가 가능하도록 개선했습니다. Target에 없는 칼럼은 무시하고, 있는 칼럼만 선별적으로 반영하여 운영 편의성을 극대화했습니다. * **성능 최적화:** 기존 대비 10배 이상의 QPS를 처리할 수 있는 구조를 설계했으며, CDC 이벤트 발행 후 최종 복제 완료까지 1초 이내의 지연 시간을 달성했습니다. * **모니터링 강화:** 복제 주체(ergate_yn)와 Source 커밋 시간(rpc_time)을 전용 칼럼으로 추가하여 데이터의 이력을 추적할 수 있는 가시성을 확보했습니다. 성공적인 DB 복제 도구 전환을 위해서는 단순히 성능이 좋은 엔진을 선택하는 것을 넘어, **운영 주체인 개발자가 익숙한 기술 스택을 적재적소에 배치**하는 것이 중요합니다. 스트림 처리는 Flink에 맡기고 복잡한 복구 로직은 Spring으로 분리한 ergate의 사례처럼, 도구의 장점을 극대화하면서도 유지보수성을 놓치지 않는 아키텍처 설계가 대규모 금융 플랫폼의 안정성을 뒷받침합니다.

넷플릭스에서 Write-Ahead (새 탭에서 열림)

넷플릭스는 대규모 데이터 환경에서 발생하는 데이터 손실, 시스템 엔트로피, 복제 및 재시도 메커니즘의 한계를 극복하기 위해 분산 **Write-Ahead Log(WAL)** 추상화 레이어를 구축했습니다. 이 시스템은 데이터 변경 사항을 캡처하고 강력한 내구성을 보장하며 하위 소비자에게 데이터를 안정적으로 전달하는 단일 인터페이스를 제공합니다. 결과적으로 개발자는 복잡한 데이터 정합성 문제를 직접 해결할 필요 없이 비즈니스 로직에 집중할 수 있게 되었으며, 플랫폼 전반의 탄력성과 운영 효율성이 크게 향상되었습니다. **WAL의 핵심 구조와 유연한 API** * **WriteToLog API:** 단순한 인터페이스를 통해 내부 구현을 추상화하며, 데이터 내구성을 '성공/실패/알 수 없음'의 세 가지 상태(Trilean)로 반환하여 신뢰성을 높였습니다. * **네임스페이스(Namespace):** 데이터의 저장 위치와 방식을 정의하는 논리적 격리 단위로, 설정에 따라 Kafka, SQS 등 다양한 기반 스토리지를 선택할 수 있습니다. * **페르소나 기반 아키텍처:** 네임스페이스 설정에 따라 지연 큐, 복제 도구, 인덱싱 도구 등 목적에 맞는 다양한 '페르소나'로 동작합니다. **지연 큐와 신뢰할 수 있는 재시도 메커니즘** * 네트워크 오류나 다운스트림 서비스 장애 발생 시 데이터 처리 처리량을 희생하지 않고도 실패한 메시지를 안전하게 재시도합니다. * SQS를 기본 스토리지로 활용하여 메시지 전달 시점을 조절하는 지연 기능을 구현함으로써 실시간 데이터 파이프라인의 안정성을 확보했습니다. **범용 교차 리전 복제 및 데이터 동기화** * Kafka를 활용하여 서로 다른 리전 간에 데이터를 복제하며, 기본적으로 복제를 지원하지 않는 스토리지 엔진에서도 리전 간 데이터 정합성을 유지할 수 있게 합니다. * Key-Value 저장소와 Elasticsearch 같은 서로 다른 데이터 저장소 간의 상태를 동기화하여 구체화된 뷰(Materialized Views)나 보조 인덱스를 안정적으로 구축합니다. **안정적인 데이터 삭제 및 부하 관리** * 데이터베이스에서 대량의 데이터를 삭제할 때 발생하는 메모리 부족(OOM) 문제를 해결하기 위해 WAL을 활용합니다. * 삭제 요청을 WAL에 기록한 후 처리 속도를 제어(Rate-limiting)하거나 예약된 시간에 실행함으로써 데이터베이스 노드에 가해지는 충격을 완화합니다. **시스템 설계 원칙과 격리 전략** * **수집 및 소비의 분리:** 고가용성 수집 레이어와 신뢰 중심의 소비 레이어를 분리하여 트래픽 급증이나 다운스트림 장애가 전체 시스템으로 전이되는 것을 방지합니다. * **멀티테넌시와 격리:** 공유 리소스를 사용하되 네임스페이스별로 격리된 리소스 풀을 할당하여 특정 작업이 다른 서비스의 성능에 영향을 주지 않도록 설계되었습니다. 데이터 플랫폼 차원의 통합 WAL 솔루션 도입은 각 서비스 팀이 개별적으로 구축하던 복제 및 재시도 로직의 중복을 제거하고 기술 부채를 크게 줄여줍니다. 대규모 분산 시스템을 운영하는 조직이라면 데이터의 최종 정합성과 시스템 탄력성을 확보하기 위해 이러한 추상화된 로그 계층을 검토하는 것이 권장됩니다.

에어비앤비의 차세대 (새 탭에서 열림)

에어비앤비는 기존의 키-값(Key-Value) 저장소인 Mussel v1의 운영 복잡성과 확장성 한계를 극복하기 위해, NewSQL 백엔드 기반의 Mussel v2로 아키텍처를 전면 재설계했습니다. 새로운 시스템은 쿠버네티스 네이티브 환경에서 대규모 벌크 로드와 실시간 스트리밍 처리를 동시에 지원하며, 한 자릿수 밀리초 단위의 읽기 성능을 안정적으로 제공합니다. 결과적으로 에어비앤비는 데이터 일관성 제어권 확보와 비용 투명성 강화는 물론, 미션 크리티컬한 서비스들을 중단 없이 성공적으로 마이그레이션하는 성과를 거두었습니다. ### v1의 한계와 재설계 배경 * **운영 복잡성:** EC2와 Chef 스크립트에 의존했던 v1은 노드 확장이나 교체에 수 시간이 소요되었으나, v2는 쿠버네티스 매니페스트를 통한 자동화로 이를 수 분 이내로 단축했습니다. * **데이터 핫스팟:** 정적 해시 파티셔닝(Static Hash Partitioning) 방식은 특정 노드에 부하가 쏠리는 문제를 야기했으나, v2는 동적 범위 샤딩(Dynamic Range Sharding)을 도입하여 100TB 이상의 테이블에서도 안정적인 지연 시간을 유지합니다. * **가시성 부족:** 리소스 사용량이 불투명했던 과거와 달리, v2는 네임스페이스별 테넌시 관리와 쿼터 할당, 대시보드를 통해 비용 통제력을 높였습니다. ### Mussel v2의 핵심 아키텍처 * **Dispatcher:** 상태가 없는(Stateless) 쿠버네티스 서비스로, 클라이언트의 API 호출을 백엔드 쿼리로 변환하며 이중 쓰기(Dual-write)와 섀도우 리드(Shadow-read)를 관리합니다. * **이벤트 기반 쓰기:** 모든 쓰기 작업은 내구성을 위해 Kafka에 먼저 기록된 후 Replayer를 통해 백엔드에 반영되어, 트래픽 급증을 유연하게 흡수하고 일관성을 보장합니다. * **읽기 최적화:** 논리적 테이블 매핑을 통해 포인트 룩업, 범위 쿼리, 접두사 쿼리를 최적화하며, 지연 시간을 줄이기 위해 로컬 복제본으로부터의 읽기(Stale Read) 기능을 제공합니다. ### 벌크 로드 및 데이터 만료(TTL) 시스템 * **고성능 인입:** S3에 업로드된 대규모 데이터를 쿠버네티스 워커 플릿이 병렬로 처리하여 기존 테이블에 병합하거나 교체하는 벌크 로드 프로세스를 최적화했습니다. * **토폴로지 인지형 TTL:** 데이터 범위를 서브 태스크로 나누어 병렬로 스캔하고 삭제하는 서비스를 도입하여, 대규모 데이터셋에서도 라이브 쿼리에 영향을 주지 않고 효율적으로 스토리지를 관리합니다. ### 무중단 마이그레이션 전략 * **Blue/Green 방식 적용:** 기존 v1에 CDC(Change Data Capture) 기능이 부족했음에도 불구하고, Kafka 스트림을 활용한 맞춤형 파이프라인을 구축해 v1과 v2 간의 최종 일관성을 유지했습니다. * **단계적 전환:** 모든 트래픽을 v1으로 보내는 단계부터 v2에서 성능을 검증하는 섀도우 단계, v2를 주 저장소로 사용하는 리버스 단계를 거쳐 최종 컷오버(Cutover)를 진행했습니다. * **안정성 장치:** 테이블 단위로 마이그레이션을 수행하고 자동 서킷 브레이커와 즉시 롤백 로직을 구현하여, 데이터 손실이나 서비스 중단 없이 100개 이상의 유스케이스를 이전했습니다. 성공적인 저장소 엔진 교체는 단순히 성능 향상에 그치지 않고, 운영 자동화와 유연한 확장성을 통해 비즈니스 요구사항에 기민하게 대응할 수 있는 기반을 마련해 줍니다. 특히 대규모 데이터 마이그레이션 시 Kafka를 중간 매개체로 활용하고 단계별 검증 과정을 거치는 전략은 시스템 안정성을 확보하는 데 필수적인 요소입니다.

DDD를 Merchant 시스템 구축에 활용한 사례를 소개합니다 (새 탭에서 열림)

기존의 음식 배달 중심 시스템에서 벗어나 소매 상품 판매에 최적화된 새로운 Merchant 시스템을 구축하기 위해 도메인 주도 설계(DDD)를 도입했습니다. 이번 프로젝트는 DDD가 단순히 코드 구현 기술이 아니라, 도메인의 역할과 책임을 명확히 정의하고 이를 바탕으로 조직 구조와 협업 방식을 설계하는 방법론임을 보여줍니다. 클린 아키텍처와 비동기 이벤트 기반의 모듈 구성을 통해 시스템의 확장성을 확보하고, 글로벌 팀 간의 원활한 협업 체계를 마련하며 성공적으로 시스템을 론칭했습니다. **소매 플랫폼으로의 전환과 도메인 정의** * 기존 시스템의 '음식점 기반 소매 판매' 한계를 극복하기 위해 독립적인 Merchant 시스템을 설계했습니다. * Merchant 시스템은 점포, 상품, 재고 등의 정보를 제공하고, 실제 판매는 '소비자 플랫폼'에서 담당하는 구조로 역할을 분리했습니다. * 핵심 도메인을 점포(shop), 상품(item), 카테고리(category), 재고(inventory), 주문(order)의 다섯 가지로 정의하여 복잡도를 낮추었습니다. **클린 아키텍처를 활용한 시스템 설계** * 도메인 엔티티가 외부 환경의 변화에 영향을 받지 않도록 클린 아키텍처를 채택했습니다. * 모든 팀원이 쉽게 이해하고 따를 수 있는 명확한 계층 구조를 통해 유지보수 편의성을 높였습니다. * 의존성 방향을 내부(도메인)로만 허용하여 비즈니스 로직의 순수성을 유지했습니다. **비동기 기반의 모듈 및 통신 구조** * 시스템을 외부 요청을 받는 'API' 모듈과 비즈니스 로직을 처리하는 '엔진' 모듈로 분리하여 가용성을 높였습니다. * gRPC를 통한 API 제공과 Apache Kafka 기반의 내부 통신을 결합했으며, Decaton 라이브러리를 사용해 파티션 대비 높은 처리량을 확보했습니다. * 플랫폼 특성을 고려하여 즉각적인 응답보다는 최종 일관성(Eventual Consistency)과 빠른 API 응답 능력에 초점을 맞춘 비동기 구조를 설계했습니다. **글로벌 협업과 조직의 일치(Conway's Law)** * 한국 팀은 핵심 도메인(Core)을, 일본 팀은 현지 시스템 연계(Link, BFF)를 담당하도록 조직을 구성해 콘웨이의 법칙을 실천했습니다. * 의사결정 과정과 논의 배경을 기록하는 ADR(Architectural Decision Record)을 활용해 조직 간의 공감대를 형성하고 불필요한 재논의를 방지했습니다. * 추상화된 연계 계층을 통해 새로운 소비자 플랫폼이 추가되더라도 핵심 도메인의 변화는 최소화되는 유연한 구조를 만들었습니다. 성공적인 DDD 적용을 위해서는 헥사고날 아키텍처와 같은 기술적인 구현에만 매몰되지 않는 것이 중요합니다. 도메인의 역할과 책임을 먼저 명확히 정의하고, 그 경계에 맞춰 팀 조직과 소통 구조를 설계할 때 진정한 설계의 이점을 얻을 수 있습니다. 시스템의 아키텍처가 조직의 소통 구조를 반영한다는 점을 인지하고, 기술과 조직 관리의 균형을 맞추는 접근이 권장됩니다.

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

피그마(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 기술 스택을 도입함으로써 비용과 성능 문제를 근본적으로 해결할 수 있습니다. 특히 대규모 환경에서는 벤더 종속성을 탈피한 자체 아키텍처 설계가 장기적인 확장성 면에서 더 유리할 수 있습니다.