피드로 돌아가기
뱅크샐러드 기술블로그Infrastructure
원문 읽기
점점 커지는 RDB Table, S3로 귀양 보내고 Athena로 불러오기 - feat. Optimization with Spark Bucketing
뱅크샐러드 Core Infra 팀이 MySQL 테이블을 S3+Athena로 마이그레이션하면서 Spark Bucketing을 적용해 S3 Object 호출 비용을 700배 감소
AI 요약
Context
신용올리기 서비스는 1년치 마이데이터를 MySQL에 저장했으나, 서비스 성장에 따라 로그가 증가하면서 저장 비용이 급증했다. MySQL에서 데이터를 읽을 때마다 전체 1년 데이터를 스캔해야 했으므로 비용 최적화가 필수적이었다.
Technical Solution
- 마이데이터 이벤트를 Kafka로 수집 후 Spark Job으로 S3에 Parquet 형식으로 저장: Kafka → Spark → S3 파이프라인 구축
- 버켓팅(bucketing)을 user_id 기준으로 적용: 필요한 유저의 데이터만 포함된 파일 1개만 읽도록 변경
- 시간 단위 파티션(dt, hour)을 일 단위 파티션(dt)으로 단순화: 파티션당 Object 호출 수를 24배 감소
- Spark repartition으로 파일 개수 제어: bucketing_key와 bucket_number로 미리 repartition하여 파티션당 정확히 1개 파일 생성
- Athena CTAS(CREATE TABLE AS) 워크플로우 도입: Spark Bucketing과 Athena 호환성 문제 해결을 위해 임시 테이블 생성-제거 방식 적용
Impact
- S3 Object 호출 비용: 700배 감소
- 파티션당 Object 호출 수: 30개 × 24시간 × 365일 → 1개 × 1일 × 365일로 감소
- 전체 인프라 비용: MySQL 저장 비용 감소가 Athena 호출 비용 증가의 3배로 상쇄
Key Takeaway
S3 기반 데이터 레이크에서 Athena로 특정 엔티티(유저, 주문 ID 등)의 데이터를 자주 조회하는 패턴에서는, 고카디널리티 컬럼을 기준으로 bucketing을 적용하고 Spark의 repartition을 통해 파일 개수를 제어해야 S3 API 호출 비용을 최소화할 수 있다.
실천 포인트
S3에 이벤트 데이터를 저장하고 Athena로 쿼리하는 서비스에서, bucketing을 user_id 같은 조회 대상 컬럼에 적용하되 Spark 특성상 executor 수 × bucket 수만큼 파일이 생성되므로 repartition으로 사전 제어하면, Object 호출 수를 획기적으로 줄여 스캔 비용을 700배 이상 절감할 수 있다.