Taming S3 Shuffle at Scale
Author: Manoj Babu Katragadda, Meghanath Macha | Source: https://blog.platform.zerotoone.ai/blog/taming-s3-shuffle-at-scale/ | Published: 2026-03-30
한 줄 요약
S3 shuffle 플러그인을 대규모로 운영할 때 발생하는 GET 요청 폭발(O(M x R)), S3 prefix 스로틀링, 스레딩 데드락 문제를 설정 튜닝과 프로덕션 패치로 해결하여 S3 API 비용을 95% 이상 절감하고 안정적인 고동시성 실행을 달성했다.
핵심 주장/내용
- S3 shuffle 플러그인은 map task당 하나의 .data 파일을 생성하므로, S3 GET 요청이 O(mappers x reducers)로 폭발적으로 증가하며, 입력 파일 coalesce와 shuffle partition 튜닝만으로 GET 수를 10배 이상 줄일 수 있다
- S3는 prefix당 5,500 GET/s, 3,500 PUT/s 제한이 있어, 기본 10개 prefix로는 수천만 GET 처리 시 503 SlowDown 에러가 발생하므로 folderPrefixes를 500까지 확장해야 한다
- ConcurrentObjectMap의 TrieMap 기반 비원자적 락 생성 → ConcurrentHashMap.computeIfAbsent로 원자적 per-key 락으로 교체하여 캐시 손상 해결
- S3BufferedPrefetchIterator의 단일 모니터 락으로 인한 메모리 락 데드락 → 메모리 관리용 별도 락 분리, LinkedBlockingDeque 도입, 5초/30초 타임아웃 적용
- supportsReliableStorage() 선언 추가로 spot 인스턴스 decommission 시 불필요한 shuffle block 복제를 방지
주요 수치 / 사실
- GET 요청 규모: 3개월 백필 시 4,500만 GET → coalesce 후 ~400만 GET/stage (10배 감소)
- S3 GET 비용: 36 → 최적화 후 대폭 절감
- S3 prefix 제한: 5,500 GET/s, 3,500 PUT/s per prefix
- S3A 클라이언트 설정: 500 connections/threads, 256MB shuffle buffer, LZ4 압축
- Spot 인스턴스 컴퓨트 절감: 70-85%, Karpenter 교체 시간 ~30초
- 포크 대상: Spark 4.0, Scala 2.13
관련 위키
Source: 원문 보기