Apache Spark 4.0에서 Spark Connect로 통합하는 ML·AI 워크로드

Apache Spark 4.0의 Spark Connect, TorchDistributor, 분산 딥러닝과 배치·스트리밍·ML 통합 아키텍처를 정리한다.

2026-08-14 · 최초 발행 2026-05-05

클라이언트와 실행 엔진을 분리한 Spark Connect

Apache Spark 4.0은 2025년 5월 출시됐다. 이번 릴리스에는 5,100개 이상의 이슈 해결과 390명 이상의 기여가 포함됐고, 기존의 배치·스트리밍·SQL 엔진 위에 ML·AI 워크로드를 네이티브로 처리하는 계층이 더해졌다.

Spark Connect는 4.0에서 프로덕션 준비 상태가 됐다. 이 구조의 핵심은 애플리케이션 프로세스와 Spark 실행 엔진을 물리적으로 떼어 놓는 데 있다. 클라이언트에서 작성한 DataFrame 연산은 실행되지 않은 논리 쿼리 계획으로 변환된다. 이 계획은 Protocol Buffers로 직렬화돼 gRPC HTTP/2 채널을 따라 서버로 전달되고, 서버는 이를 해석·최적화한 뒤 실행한다. 결과는 Apache Arrow로 인코딩된 행 배치 형태로 다시 스트리밍된다.

Spark Execution EnginegRPC Transport LayerClient SideHTTP/2 + gRPCArrow Row BatchesPython / Scala / GoDataFrame APIUnresolved Logical PlanProtocol Buffers 직렬화Spark Connect Server결과 스트리밍Plan ResolverCatalyst OptimizerPhysical PlanSpark Executor 1Spark Executor 2Spark Executor N

이 분리는 언어 경계와 장애 경계를 함께 바꾼다. Python, Scala, Java뿐 아니라 Go, Swift, Rust 클라이언트도 추가됐다. 클라이언트 장애가 서버와 클러스터에 직접 영향을 주지 않으며, gRPC HTTP/2의 인증 프록시 지원을 이용하면 Spark 내부에 인증 로직을 넣지 않고도 엔터프라이즈 접근 제어를 구성할 수 있다.

spark.api.mode로 Classic 모드와 Connect 모드를 전환할 수 있어 기존 환경을 옮길 경로도 마련돼 있다. MLlib의 전체 기능 역시 Spark Connect를 통해 접근할 수 있다.

PyTorch 학습과 추론을 Spark 실행기에 올리는 방식

TorchDistributor는 3.4에서 도입됐으며, 4.0에서 프로덕션 수준으로 성숙했다. 기존 PyTorch 학습 루프나 PyTorch Lightning 트레이너를 TorchDistributor.run()으로 감싸면 Spark가 여러 실행기에 분산해 실행한다.

from pyspark.ml.torch.distributor import TorchDistributor

def train_fn():
    import torch
    # 기존 PyTorch 학습 코드 그대로 사용
    model = MyModel()
    trainer = pl.Trainer(max_epochs=10, devices="auto")
    trainer.fit(model, dataloader)
    return model.state_dict()

distributor = TorchDistributor(
    num_processes=8,     # Spark 실행기 수
    local_mode=False,    # 분산 모드
    use_gpu=True
)
result = distributor.run(train_fn)

실행은 배리어 실행 모드로 조율된다. 모든 작업이 함께 시작되고, 각 실행기는 GPU를 독립적으로 사용한다. 그래디언트 동기화에는 AllReduce 방식이 사용된다.

추론 경로에서는 레코드마다 UDF를 호출할 때 생기던 오버헤드를 줄인다. Spark는 데이터를 Apache Arrow 배치로 벡터화해 실행기에 전달하며, 워커 프로세스에 모델을 캐시한다. 따라서 배치마다 모델을 다시 로드할 필요가 없다. Apache Arrow 직렬화를 활용한 Python UDF 성능은 1.5배 이상 향상됐다.

그래디언트를 맞추는 동기화 패턴

Spark 4.0 기반 분산 딥러닝은 AllReduce와 파라미터 서버라는 두 동기화 패턴을 지원한다.

Spark Barrier SchedulerAllReduce 방식 (Ring-AllReduce)그래디언트그래디언트그래디언트집계 완료동시 시작 보장동시 시작 보장동시 시작 보장동시 시작 보장파라미터 서버 방식최신 파라미터최신 파라미터최신 파라미터그래디언트 Push그래디언트 Push그래디언트 PushParameter Server(중앙 집중)Worker 1Worker 2Worker 3Worker 1GPUWorker 2GPUWorker 3GPUWorker 4GPU배리어 스케줄러

AllReduce, 특히 Ring-AllReduce는 TorchDistributor를 Horovod나 PyTorch DDP와 연계할 때 사용된다. 워커들은 인접 워커와 그래디언트를 교환하고, 중앙 서버 없이 집계를 끝낸다. Spark의 배리어 스케줄러는 작업을 동시에 시작하도록 보장해 스트래글러로 인한 교착을 방지한다.

BigDL 등의 프레임워크가 채택한 파라미터 서버 방식에서는 중앙 서버가 최신 가중치를 관리한다. 워커는 비동기적으로 그래디언트를 Push한다. 워커 간 속도 차이에 강건한 대신 부실 그래디언트(stale gradient)가 발생할 수 있다.

RAPIDS 라이브러리와 결합하면 GPU 가속이 더해져 데이터 준비와 모델 학습 양쪽에서 더 큰 성능 향상을 얻을 수 있다.

배치·스트리밍·ML을 한 엔진에서 다루는 구성

Spark 4.0의 통합 엔진은 SQL, 배치 처리, 스트리밍, ML, 시각화를 하나의 데이터 플랫폼 안에 둔다.

레이어 컴포넌트 Spark 4.0 변경사항
SQL·구조화 데이터 Spark SQL ANSI 기본 활성화, VARIANT 타입, PIPE(|>) 구문
배치 처리 DataFrame / Dataset API Spark Connect 기반 언어 독립화
스트리밍 Structured Streaming transformWithState API, RTM(100ms 미만 지연)
ML MLlib + TorchDistributor 분산 딥러닝 네이티브 지원
시각화 PySpark Native Plotting Plotly 기반 네이티브 DataFrame 플롯

transformWithState API는 스트리밍 파이프라인에서 임의 상태를 관리하는 방식이다. 기존 mapGroupsWithStateflatMapGroupsWithState를 통합·개선했고, 유입 이벤트를 바탕으로 하는 복잡 이벤트 처리(CEP)를 더 직관적으로 구성할 수 있게 했다. Spark 4.1.0(2025년 12월)에서 공식화된 Real-Time Mode(RTM)는 연속 처리로 100ms 미만 지연을 달성한다.

DataFrame에서 바로 그리는 시각화

Spark 4.0에서는 pandas 변환이나 외부 라이브러리 없이 PySpark DataFrame에서 시각화를 생성할 수 있다.

# Pandas 변환 없이 바로 플롯
df.plot(x="timestamp", y="value", kind="line")
df.plot.bar(x="category", y="count")
df.plot.scatter(x="feature_a", y="feature_b")
df.plot.hist(column="revenue", bins=50)

Line, Bar, Area, Scatter, Pie, Box, Histogram, Density/KDE 차트를 지원한다. 내부 백엔드는 Plotly다. 소규모 플롯은 1,000행을 샘플링하고, 큰 데이터셋은 저수지 샘플링(reservoir sampling)으로 단일 패스 처리한다. SQL 측 최적화와 코드 생성을 지원하는 내부 SQL 식을 활용해 플로팅 워크플로우는 기존 대비 5~10배 빠르다.

기존 Spark 환경을 옮길 때 확인할 변경점

Spark 2.x 또는 3.x에서 4.x로 전환할 때는 라이브러리와 SQL 동작, 운영 연동 지점을 함께 확인해야 한다.

javax.servlet을 참조하는 커스텀 플러그인이나 의존성은 jakarta.servlet으로 바꿔야 한다. 내부 javax servlet API 참조가 jakarta로 변경됐기 때문이다.

ANSI SQL이 기본으로 활성화되면서 0으로 나누기, 유효하지 않은 캐스트, 타입 불일치는 오류가 된다. 암묵적 형 변환이나 NULL 반환에 기대고 있던 코드는 수정 대상이다. 임시 대응으로 spark.sql.ansi.enabled=false를 설정할 수 있지만, 장기적으로는 코드를 수정하는 편이 권장된다.

추측적 실행 정책의 기본값도 더 보수적으로 변경됐다. multiplier=3, quantile=0.9가 적용되며, 기존 동작인 1.5/0.75가 필요하면 명시적으로 설정해야 한다. 이벤트 로그는 기본적으로 증분 롤링·압축되므로 로그 파일을 직접 파싱하는 외부 모니터링 시스템도 이 변화를 처리해야 한다.

Structured Streaming에서 mapGroupsWithState 또는 flatMapGroupsWithState를 사용하고 있다면 transformWithState 전환을 검토할 수 있다. 기존 API는 계속 동작하지만, 새 API가 더 풍부한 상태 관리 기능을 제공한다.

전환은 spark.api.mode=classic으로 Spark Connect를 비활성화한 상태에서 4.0으로 먼저 올리고, ANSI 오류를 수정한 다음 Connect 모드를 점진적으로 활성화하는 흐름이 권장된다.

워크로드별로 드러나는 성능 변화

SQL 워크로드는 전반적으로 20~40% 빨라졌다. 대소문자를 무시하는 필터링, 즉 LOWER() 비교에서는 최대 22배, STARTSWITHENDSWITH 함수에서는 최대 10배 향상이 보고됐다.

ML에서는 엔드투엔드 학습 파이프라인이 2030% 빨라졌고, 전체 ML 파이프라인은 23배 향상됐다. 앞서 언급한 Python UDF는 1.5배 이상, 플로팅 워크플로우는 5~10배 빨라졌다. 스케줄링에서는 적응형 쿼리 실행(AQE)이 실시간 데이터 크기에 따라 조인 전략을 자동 전환해 스큐 처리를 효율화한다.

Spark Connect의 gRPC 기반 분리, TorchDistributor를 이용한 분산 학습, 그리고 배치·스트리밍·SQL·ML·시각화를 아우르는 통합 엔진은 Spark 4.0을 데이터 처리 프레임워크에서 통합 AI·ML 실행 플랫폼으로 확장한다.

Sources

Apache SparkSpark Connect분산 딥러닝PyTorch빅데이터