← 학습 카테고리

Learn

Spark

84개 모듈 · 현재 50번째

Spark 모듈 50/84 spark-learn-50

Whole-Stage Code Generation — Volcano 모델을 깨고 여러 연산을 함수 하나로

Apache Spark Whole-Stage Code Generation 및 Kubernetes 배포 공식 문서·기술 자료 종합 (웹 리서치, 2026) — Apache Spark 공식 문서(running-on-kubernetes.html) + japila.pl Mastering Spark SQL(WholeStageCodegenExec) japila.pl Mastering Spark SQL — Whole-Stage Java Code Generation

이 모듈을 다 읽으면

  • 전통적인 Volcano 반복자 모델의 오버헤드가 무엇인지 설명할 수 있다
  • Whole-Stage Code Generation이 이 오버헤드를 어떻게 없애는지, 그리고 어디서 경계가 나뉘는지 판단할 수 있다

spark-learn-24에서 한 문장으로 스쳐 지나간 Whole-Stage Code Generation을, 전통적인 Volcano 반복자 모델과 대비해 그 메커니즘을 구체화한다.

Volcano 반복자 모델의 비용 — 연산마다 함수 호출

전통적인 질의 실행 엔진(Volcano/반복자 모델)은 쿼리 트리의 각 연산자(필터, 프로젝션, 조인 등)가 next() 같은 메서드로 한 번에 행 하나씩만 처리하고, 그 결과를 상위 연산자에 넘겨준다. 연산자가 여러 단계로 쌓이면(filter → project → aggregate 등), 행 하나가 최종 결과까지 가는 데 그 단계 수만큼 가상 함수 호출(virtual function call)을 거쳐야 한다 — 데이터 자체의 처리 비용보다 이 호출 오버헤드가 더 클 정도로, 행이 많을수록 누적 비용이 커진다.

핵심 포인트

  • Volcano 모델은 연산자마다 next()로 행 하나씩 처리해 상위로 넘기는 방식 — 연산자 단계 수만큼 가상 함수 호출이 누적된다

Whole-Stage Code Generation — 여러 연산자를 하나의 함수로 합친다(operator fusing)

Whole-Stage Code Generation(WSCG)은 이 문제를 거꾸로 접근한다 — 여러 물리 연산자를 각자 실행하는 대신, 그 연산자들의 로직을 미리 분석해 하나의 Java 함수로 직접 생성(코드 생성)한다. 이러면 연산자 사이를 오가는 가상 함수 호출 자체가 사라지고(operator fusing이라 부른다), 생성된 코드가 JIT 컴파일러의 최적화(레지스터 활용 등) 혜택도 더 잘 받는다. 이 방식은 각 연산자가 한 번에 한 행만 처리한다는 Volcano 모델의 전제를 사실상 깨는 것이다 — 여러 연산이 한 함수 안에서 그 행에 대해 순서대로 다 처리되고 나서야 다음 행으로 넘어간다.

핵심 포인트

  • WSCG은 여러 물리 연산자의 로직을 하나의 Java 함수로 코드 생성(operator fusing)해 연산자 간 가상 함수 호출을 없앤다
  • Volcano 모델의 '한 번에 한 행씩, 연산자 단위로' 처리한다는 전제를 사실상 깨는 방식

경계는 셔플에서 나뉘고, 모든 연산자가 다 융합되지는 않는다

하나의 함수로 융합할 수 있는 범위(스테이지)는 무한정 크지 않다 — 데이터가 노드 간 재분배되는 셔플이 일어나는 지점에서 스테이지 경계가 나뉜다(셔플 자체가 네트워크를 거치는 별개의 물리적 단계이기 때문). 또한 모든 연산자가 코드 생성을 지원하는 것도 아니다 — 지원하지 않는 연산자를 만나거나, 생성된 코드의 컴파일이 실패하면(spark.sql.codegen.fallback 설정에 따라) Spark는 그 부분만 전통적인 반복자 모델(또는 벡터화 실행)로 폴백해서 처리한다. 즉 WSCG은 '전체를 항상 다 융합하는 것'이 아니라, 융합 가능한 구간을 최대한 찾아 적용하고 나머지는 기존 방식으로 처리하는 하이브리드 전략이다.

핵심 포인트

  • 셔플이 일어나는 지점에서 스테이지 경계가 나뉜다 — 셔플을 넘어 하나의 함수로 융합할 수는 없다
  • 코드 생성을 지원 안 하는 연산자나 컴파일 실패 시 전통적 반복자 모델로 폴백(spark.sql.codegen.fallback) — 항상 전체가 융합되는 게 아니라 하이브리드 전략