AI Briefing

Pinterest의 Apache Spark OOM 오류를 대폭 줄인 방법

·2026.02.18 02:01

Pinterest는 Auto Memory Retries로 Spark OOM 실패를 96% 줄였다.

Pinterest는 대규모 Apache Spark 환경에서 OOM(out-of-memory) 실패를 줄이기 위해, 실패한 task를 더 큰 executor에서 자동 재시도하는 Auto Memory Retries를 도입했다.

클러스터는 Kubernetes 위에서 운영되며, 하루 9만+ Spark job수백 PB 규모의 shuffle을 처리한다. 기존에는 executor 메모리를 무작정 키우기 어렵고, job마다 stage와 task의 메모리 요구량이 달라 수동 튜닝만으로는 한계가 있었다.

핵심 아이디어는 task 단위로 resource profile을 분리하는 것이다. OOM이 발생하면 먼저 cpus per task를 늘려 같은 default executor에서 재시도하고, 그래도 실패하면 더 큰 physical executor를 새로 띄운다. 이때 base profile 등록 시 2x, 3x, 4x의 immutable retry profile을 함께 만들어 순차적으로 사용하며, off-heap memory가 켜진 경우에는 그것도 함께 확장한다.

이를 위해 Task, TaskSetManager, TaskSchedulerImpl, ExecutorAllocationManager를 확장했다.

  • Task는 부모 TaskSet과 다른 경우를 나타내는 optional taskRpId를 가진다.
  • TaskSetManager는 OOM 실패 시 다음 retry profile을 자동 할당하고, profile별 task index를 관리한다.
  • TaskSchedulerImpl은 증가된 CPU 설정의 task를 default executor에도 배치해 기존 자원을 최대한 재사용한다.
  • ExecutorAllocationManager는 retry profile별 pending task 수를 추적하고, 필요한 경우 더 큰 executor를 띄운다.

실행 시에는 SparkListener 대신 Pinterest 전용 하위 클래스를 만들어 필요한 함수만 override했기 때문에, 기능이 꺼져 있을 때는 기존 Spark 동작을 유지하고 켜졌을 때만 새 로직이 동작하도록 설계했다. SparkUI에도 task resource profile id를 표시해 운영자가 재시도 상태를 쉽게 볼 수 있게 했다.

롤아웃은 ad hoc submission부터 **0%→100%**로 넓힌 뒤, scheduled job을 Tier 3 → Tier 2 → Tier 1 순으로 확장했다. 대시보드는 recovered job 수, saved MB-seconds, saved vcore-seconds, retry 후 실패한 job 수 등을 추적했고, 최종적으로 전체 OOM 실패가 96% 감소했다.

학습한 점도 분명했다. 매우 큰 TaskSet에서는 활성 profile을 찾는 과정이 느려질 수 있어 인덱스를 추가로 만들었고, Apache Gluten처럼 application 시작 이후 resource profile을 등록하는 경우와 Scala/PySpark 사용자가 직접 profile을 등록하는 경우까지 고려해 retry profile 생성 시점을 조정했다.

이 요약은 원문 이해를 돕기 위한 큐레이션입니다. 저작권은 원저작자에게 있으며, 정확한 내용과 맥락은 원문을 확인하세요.

요약 오류, 출처 표기 문제, 삭제 요청은 문의 · 건의로 알려주세요.