물리 파티션 한계인 1,000 WCU의 벽을 깨고, 단 1회의 쿼리로 조회가 가능한 결정적 샤딩 프레임워크를 구축하다
본 아티클은 채널톡이 DynamoDB 인프라에서 급증하는 대규모 프로모션 트래픽(Boot 요청)을 안정적으로 수용하기 위해 '쓰기 샤딩(Write Sharding)' 기법을 도입한 생생한 여정을 담고 있습니다. 물리적 한계를 극복하기 위해 설계한 공통 샤딩 프레임워크부터, 20억 건의 데이터를 백필하는 도중에 발생한 예기치 못한 '롤링 핫 파티션' 쓰로틀링 에러를 셔플 기법으로 해결해 나간 구체적인 아키텍처적 도전과 솔루션을 전달합니다.
NoSQL(DynamoDB 등) 환경에서 특정 키에 부하가 쏠리는 '핫 파티션' 현상으로 시스템 아키텍처 교체를 고민 중이거나, 대량의 데이터(수십억 건 단위)를 중단 없이 고성능으로 마이그레이션하려는 백엔드 및 DevOps 개발자들에게 실전 문제해결서로 적극 권장합니다.
채널톡의 member GSI가 channelId를 파티션 키로 사용하면서 특정 채널에 대규모 부트(Boot) 트래픽이 집중될 때 DynamoDB의 물리 파티션당 처리 한계인 초당 1,000 WCU를 초과하여 쓰로틀링이 발생했습니다. 이 쓰로틀링이 백프레셔로 작용하여 메인 User 테이블의 쓰기 작업까지 거부시켰고, 결과적으로 서비스 무중단 운영에 심각한 장애 위협이 되었습니다.
memberId를 Murmur3 해시 함수로 연산하여 16개의 Suffix(접미사) 중 하나를 도출하고, 이를 기존 channelId와 결합해 파티션 키를 분산하는 결정적 쓰기 샤딩(Deterministic Write Sharding) 기법을 도입했습니다. 이를 안정적으로 운영하기 위해 특정 데이터베이스에 의존하지 않는 공통 쓰기 샤딩 프레임워크를 직접 설계했으며, DynamoDB Export 및 AWS Glue를 활용해 약 20억 건의 기존 데이터를 무중단 상태에서 업데이트했습니다.
특정 고객사 채널에 집중되는 부트 트래픽 수용 한계를 초당 기존 약 1,000건에서 최대 16,000건으로 약 16배 대폭 늘려 안정성을 확보했습니다. 또한 저장과 조회의 키 계산 규칙을 완벽히 일치시킴으로써 단건 조회 시 분산된 16개 샤드 상태에서도 단 1회의 Query 요청으로 조회할 수 있게 만들었으며, 20억 건의 방대한 기존 데이터를 완벽하게 마이그레이션했습니다.
Trade-off
결정적 샤딩 기법을 통해 단건 조회의 오버헤드는 제거했으나, 만약 한 그룹 전체의 사용자 목록을 조회해야 하는 패턴(Scatter-Gather)이 생길 경우 분산된 16개의 샤드를 전체 스캔한 뒤 머지 및 재정렬해야 하므로 읽기 비용이 커집니다. 또한 백필 단계에서 물리적 정렬 순서대로 가해지는 대량 쓰기가 특정 파티션에 차례대로 부하를 주는 롤링 핫 파티션 현상을 초래하여 데이터의 처리 순서를 섞는 셔플 과정을 따로 구현해야 했습니다.
단일 파티션 키에 특정 규칙 기반의 접미사(Suffix)를 결합하여 물리적으로 상이한 여러 파티션 영역에 쓰기 부하를 대폭 분산시켜 저장 공간과 성능을 확장하는 NoSQL 스케일 아웃 기법입니다.
난수나 라운드로빈 대신 사용자 ID와 같이 고유한 입력값에 해시 연산 처리를 거치게 하여 언제나 특정 입력값에 매칭되는 동일한 샤드 번호가 도출되게 하는 샤딩 전략입니다.
대용량 백필 또는 데이터 이관 진행 시, 정렬된 백업 소스 데이터의 키 순서대로 쓰기 작업이 유입되면서 시간의 경과에 따라 특정 물리 파티션별로 쓰로틀링 장애 지점이 점진적으로 이동해 발생하는 병목 현상입니다.