Apache Spark 4.2: CDC 통합·메트릭 뷰·실시간 스트리밍·Arrow 기본값으로 달라진 운영 지형
요약
2026년 7월 14일 출시된 Apache Spark 4.2.0은 단일 마이너 릴리스 치고 운영 지형을 크게 바꿀 네 가지 변화를 담고 있다.
- CDC 통합: Delta Lake, Iceberg, Hudi 각자의 증분 쿼리 방언을 하나의
CHANGES인터페이스로 통합 - Metric View: 비즈니스 지표 정의를 엔진 내부에서 관리하는 시맨틱 레이어
- 실시간 모드(RTM): 수 밀리초 지연을 목표로 하는 Structured Streaming Real-Time Mode 정식 지원
- Arrow UDF 기본화: Python UDF에 Arrow 경로를 기본값으로 전환해 직렬화 비용 제거
각각은 독립적인 운영 결정을 요구한다. 이 글은 네 변화의 내부 작동 방식과 배포 시 고려해야 할 트레이드오프를 다룬다.
- 출시일: 2026-07-14
- 공식 릴리스: https://spark.apache.org/releases/spark-release-4-2-0.html
- 주요 JIRA: SPARK-55668 (CDC 지원), SPARK-55948 (DSv2 CDC API)
배경: 왜 지금 이 네 가지인가
CDC 단편화의 누적된 고통
2024년 이후 Lakehouse 스택을 운영하는 팀은 공통된 문제에 직면했다. Delta Lake, Apache Iceberg, Apache Hudi 세 포맷이 각자 증분 데이터를 노출하는 방식이 달랐다.
- Delta Lake:
table_changes()함수 또는readChangeFeed옵션 - Iceberg:
TableChangesAPI와 삭제 벡터 - Hudi:
hoodie.datasource.query.type=incremental옵션
같은 파이프라인이 소스 포맷에 따라 완전히 다른 코드를 요구했다. 커넥터를 교체하거나 포맷을 마이그레이션할 때 파이프라인 전체를 재작성해야 했다.
Spark 4.2는 DataSource v2(DSv2) API에 Changelog 믹스인 인터페이스를 추가해 이 단편화를 해소한다.
변화 1: CHANGES 절과 DSv2 Changelog API
아키텍처
새로운 Changelog 인터페이스는 커넥터 수준의 계약이다. Delta Lake, Iceberg, Hudi 등 DSv2 커넥터가 이 인터페이스를 구현하면 Spark 플래너가 표준 CDC 쿼리를 처리한다. 커넥터는 포맷 특화 변경 이벤트를 Spark에 넘기고, 엔진이 나머지를 담당한다.
엔진이 처리하는 공통 후처리:
- Copy-on-Write에서 발생하는 중복 이벤트 제거
- INSERT+DELETE 쌍을 UPDATE로 변환
- 행 단위 순 변경(net change) 계산
커넥터는 이 로직을 직접 구현할 필요가 없다.
사용 방법
배치 모드에서 특정 버전 범위의 변경을 조회한다.
-- 버전 10에서 20 사이의 변경 이력 조회 (Open question: 정확한 문법은 공식 릴리스 노트 확인 필요)
SELECT * FROM my_table CHANGES FROM VERSION 10 TO VERSION 20;DataFrame API에서도 동일하게 사용할 수 있다.
df = spark.read \
.option("startingVersion", "10") \
.option("endingVersion", "20") \
.changes("my_table")Structured Streaming과 결합하면 실시간 CDC 파이프라인을 구성할 수 있다.
-- 스트리밍 CDC 파이프라인 (Open question: STREAM + CHANGES 결합 문법 확인 필요)
CREATE STREAMING TABLE cdc_sink AS
SELECT * FROM STREAM my_table CHANGES FROM VERSION 0;Open question: 위 SQL 문법은 연구 과정에서 합성된 것이다. 공식 Spark 4.2.0 릴리스 노트(https://spark.apache.org/releases/spark-release-4-2-0.html)에서 정확한 구문을 확인하고 사용하라.
변화 2: Auto CDC와 Spark Declarative Pipelines
Spark Declarative Pipelines(SDP)는 파이프라인 정의에서 CDC 처리를 선언적으로 지정하는 상위 레이어다. 사용자는 키 컬럼, 시퀀스 컬럼, 연산 컬럼을 선언하면 된다.
| 선언 항목 | 역할 |
|---|---|
| 키 컬럼 | UPSERT/DELETE 대상 행 식별 |
| 시퀀스 컬럼 | 이벤트 순서 결정 (타임스탬프 또는 단조 증가 ID) |
| 연산 컬럼 | INSERT/UPDATE/DELETE 구분 |
Spark는 선언에 따라 SCD Type 1 업서트를 자동 실행한다. 일치하는 키는 UPDATE, 새 키는 INSERT, 삭제 이벤트는 DELETE로 처리한다. 이전의 APPLY CHANGES INTO 문법은 이 새 API를 선호해 deprecated됐다.
변화 3: Metric View — 시맨틱 레이어를 엔진 안으로
문제: 지표 정의가 클라이언트에 분산된다
기존에는 "월별 수익" 같은 KPI를 각 대시보드 도구, BI 클라이언트, 분석 쿼리가 제각각 정의했다. 집계 함수 선택, 필터 기준, 날짜 컬럼 해석이 클라이언트마다 달라져 지표 불일치가 발생했다.
Metric View 구조
Spark 4.2는 WITH METRICS 절이 있는 특수 뷰 타입을 도입한다. 뷰 내부에 측정값(measure)과 차원(dimension)을 정의하면, 뷰를 쿼리하는 클라이언트는 집계 함수를 다시 명시하지 않고도 정의된 지표를 사용할 수 있다.
-- Metric View 생성 (Open question: WITH METRICS 문법 세부사항은 릴리스 노트 확인 필요)
CREATE VIEW revenue_metrics WITH METRICS AS
SELECT
customer_id,
order_date,
SUM(order_amount) AS total_revenue -- measure
FROM orders;주요 설계 결정:
- Metric View에는
WITH SCHEMA를 지정할 수 없다. 스키마가 측정값 정의에서 파생된다. - 경로 기반 이름 해석 모델을 도입했다.
SET PATH로 검색 경로를 설정하고,CURRENT_PATH()함수로 현재 경로를 확인할 수 있다. - AI 에이전트가 Spark를 쿼리할 때 비즈니스 지표 정의를 자동으로 발견할 수 있도록 하는 것이 설계 의도 중 하나다.
변화 4: Structured Streaming Real-Time Mode 정식 지원
마이크로배치의 지연 한계
표준 Structured Streaming은 마이크로배치 방식이다. 각 배치를 처리하고, 체크포인트를 기록하고, 다음 배치를 시작한다. 체크포인트 오버헤드로 인해 최소 지연이 수백 밀리초 수준이다.
Spark 2.3부터 실험적으로 제공된 Continuous Processing(CP) 모드는 지연을 수 밀리초 수준으로 낮추는 것을 목표로 했지만, 4.2 이전까지 실험적 상태였다.
RTM 아키텍처
Spark 4.2에서 정식 지원으로 승격된 Real-Time Mode(RTM)는 Continuous Processing을 기반으로 한다. 마이크로배치 스케줄러 대신 파티션당 하나의 장기 실행 태스크를 유지한다. 체크포인트는 에포크 단위로 기록되고, 마이크로배치 방식처럼 배치마다 커밋하지 않는다.
RTM 적합 사례:
- 무상태 변환 파이프라인 (필터링, 필드 추출, 포맷 변환)
- 이벤트 감지 (이상값 탐지, 알림 트리거)
- 지연에 민감한 스트리밍 ETL
RTM 제한사항:
- 배달 의미론이 At-Least-Once다. 중복 가능성 있으므로 멱등 싱크(idempotent sink)가 필요하다.
- 유상태(stateful) 연산(groupBy, window 집계)에 제한이 있다.
- Python Data Sources는 RTM을 지원하지만 일부 상태 연산은 제외된다.
변화 5: Arrow UDF 기본화
기존 Python UDF의 직렬화 비용
기존 Python UDF는 JVM과 Python 프로세스 사이에서 행을 직렬화해야 했다. 각 행이 Python Row 객체로 변환됐다가 다시 JVM으로 돌아오는 과정에서 Pickle/CloudPickle 직렬화가 발생했다. CPU와 메모리 모두 비쌌다.
Pandas UDF는 이미 Apache Arrow IPC 포맷을 사용해 배치 단위로 데이터를 전달했다. RecordBatch 형태로 전달하면 행 단위 직렬화 없이 처리할 수 있었지만, 사용자가 함수 시그니처를 Pandas 스타일로 바꿔야 했다.
Spark 4.2의 기본값 변경
Spark 4.2는 두 설정을 기본값 true로 전환한다.
| 설정 | 4.2 이전 기본값 | 4.2 기본값 |
|---|---|---|
spark.sql.execution.pythonUDF.arrow.enabled | false | true |
spark.sql.execution.arrow.pyspark.enabled | false | true |
일반 Python UDF(@udf)도 이제 Arrow 경로를 기본으로 사용한다. 함수 시그니처를 바꾸지 않고도 Arrow 최적화 경로를 자동으로 탄다.
from pyspark.sql.functions import udf
from pyspark.sql.types import StringType
# Spark 4.2 이후: 변경 없이 Arrow 경로 자동 사용
@udf(StringType())
def process_name(name):
return name.upper()
# Arrow 비활성화가 필요한 경우 (Arrow 호환 불가 타입)
spark.conf.set("spark.sql.execution.pythonUDF.arrow.enabled", "false")주의사항: Arrow 타입 변환이 지원되지 않는 Python 타입(예: 복잡한 커스텀 객체)을 UDF에서 사용하면 오류가 발생할 수 있다. 기존 UDF가 많은 환경에서는 업그레이드 전 Arrow 호환성 확인이 필요하다.
운영자 체크리스트
종합 판단
네 가지 변화는 독립적이지만 함께 보면 Spark 4.2의 방향성이 명확해진다. 엔진이 데이터 계층에서 더 넓은 의미를 담으려 한다. CDC는 포맷 계층의 단편화를 엔진이 흡수하고, Metric View는 BI 계층의 지표 정의를 엔진이 흡수한다. RTM은 스트리밍 레이턴시 요구사항을 더 낮은 계층에서 충족하고, Arrow UDF 기본화는 Python 생태계와의 경계 비용을 줄인다.
이 방향은 LLM 기반 데이터 에이전트가 Spark를 직접 쿼리하는 시나리오에서도 의미가 있다. Metric View로 지표 정의를 발견하고, CHANGES 절로 증분 데이터를 추출하고, RTM으로 실시간 이벤트를 처리하는 에이전트 파이프라인이 단일 Spark 세션 안에서 구성 가능해진다.
실무 우선순위는 다음 순서를 권장한다: Arrow UDF 호환성 검증(리스크 최소 대비 성능 이득 큰 변화) → CDC API 통합(포맷 이식성 개선) → RTM 검토(실제 지연 요구사항이 있는 파이프라인만) → Metric View(팀 지표 정의 관리 성숙도 도달 후).
References
- Apache Spark 4.2.0 릴리스: https://spark.apache.org/releases/spark-release-4-2-0.html
- Apache Spark 프로젝트 뉴스: https://spark.apache.org/news/spark-4-2-0-released.html
- SPARK-55668 (CDC 지원 umbrella): https://issues.apache.org/jira/browse/SPARK-55668
- SPARK-55948 (DSv2 CDC 커넥터 API + CHANGES 절): https://issues.apache.org/jira/browse/SPARK-55948
- Data+AI Summit 세션: https://www.databricks.com/dataaisummit/session/first-class-cdc-support-spark-42
- Databricks Spark 4.2 소개: https://www.databricks.com/blog/introducing-apache-spark-42
- Structured Streaming 가이드: https://spark.apache.org/docs/latest/structured-streaming-programming-guide.html