왜 지금 봐야 하나
2026년 7월 10일 공개된 Apache Arrow 25.0.0은 222개 이슈를 처리한 누적 릴리스다. 단일 기능이 폭발적인 릴리스는 아니지만, Arrow가 데이터 플랫폼 스택에서 차지하는 위치를 이해하지 못하면 숫자만 보고 넘어가기 쉽다.
Arrow가 "보이지 않는 표준"인 이유가 있다. Spark, Flink, DuckDB, Trino, ClickHouse, Polars, Pandas 2.x, dbt, PyTorch DataLoader — 이 스택 어딘가에 Arrow가 없는 경우를 찾기 어렵다. 엔진 간 데이터를 넘길 때 Arrow IPC를 쓰면 직렬화/역직렬화 변환 없이 메모리 버퍼를 포인터로 전달할 수 있다. 변환 비용이 없다는 것이 데이터 파이프라인에서 무엇을 의미하는지가 이 챕터의 핵심 주제다.
25.0.0에서 주목할 변경은 두 방향이다:
- C++ 레이어: ARM64 SVE SIMD 지원, Parquet ListView 읽기·쓰기, Bloom filter 벡터화
- 프로토콜 레이어: Flight SQL 준비 구문 메타데이터 개선, C Data Interface 변형 버퍼 처리 명세
Apache Arrow 생태계 구조
Arrow는 단일 라이브러리가 아니다. 네 가지 구성 요소가 함께 동작한다.
인메모리 컬럼형 레이아웃
버퍼 기반 · 제로 복사 가능
프로세스 간 전송
스트림 / 파일 형식
FFI 경계 없는 버퍼 공유
Python↔C++↔Rust↔Java
gRPC + Arrow IPC · 고속 대용량 전송
서버 → 클라이언트 스트리밍
Flight 위에 SQL 시맨틱 추가
Catalog · PreparedStatement · Transaction
각 레이어의 역할:
- Arrow Columnar Format: 메모리 레이아웃 명세. CPU 캐시 친화적 컬럼 지향 버퍼.
- C Data Interface: 언어 경계를 넘어 Arrow 버퍼를 복사 없이 공유하는 FFI 명세. Python ↔ C++ ↔ Rust ↔ Java 간 변환 비용 제거.
- Arrow IPC: 프로세스 간 전송 포맷. 파일(
.arrow,.feather)과 스트림 두 가지. - Arrow Flight RPC: gRPC 위에서 Arrow IPC 스트림을 고속 전송하는 프로토콜.
- Arrow Flight SQL: Flight RPC에 SQL 시맨틱(카탈로그 조회, 준비 구문, 트랜잭션)을 추가.
- ADBC (Arrow Database Connectivity): 다양한 백엔드 데이터베이스에 통일된 클라이언트 API 제공. JDBC와 목적은 같지만 Arrow 형식으로 데이터를 주고받아 변환 없음.
Arrow 25.0.0 주요 변경
C++: ARM64 SVE SIMD 동적 디스패치
25.0.0 이전까지 Arrow C++의 SIMD 동적 디스패치(CPU 기능에 따라 최적화 경로 선택)는 x86 플랫폼에서만 작동했다. 이제 ARM64(AArch64)에서도 SVE(Scalable Vector Extension) 최적화 루틴으로 동적 디스패치가 가능하다.
런타임 CPU 탐지 로직도 자체 구현에서 xsimd 라이브러리로 교체했다. xsimd는 SIMD 추상화 레이어로, AVX2/AVX-512(x86)와 SVE/NEON(ARM64)을 통일된 인터페이스로 다룬다. 유지 관리 부담을 줄이고 향후 새로운 SIMD 확장 지원을 추가할 때 기반이 된다.
데이터베이스 운영자에게 이 변화가 중요한 이유: ARM64 기반 클라우드 인스턴스(AWS Graviton, Ampere Altra 등)에서 Arrow를 사용하는 엔진의 필터링·집계 연산 처리량이 향상될 수 있다. Spark, Trino, DuckDB처럼 Arrow C++ 위에서 동작하는 엔진이 혜택을 본다.
C++: Parquet ListView 읽기·쓰기
Arrow의 ListView 타입(각 리스트 요소가 오프셋+길이로 정의되는 가변 길이 배열)을 Parquet 파일로 읽고 쓸 수 있게 됐다. 기존에는 ListView를 일반 List로 변환한 뒤 저장해야 했다.
실용적 의미: JSON 배열 컬럼, 이벤트 로그의 가변 길이 태그 배열 등을 Parquet에 저장하고 재로드할 때 Arrow 타입 정보가 손실 없이 보존된다.
C++: Bloom filter 벡터화
Parquet의 Bloom filter 연산을 SIMD로 벡터화했다. Bloom filter는 Parquet 파일 읽기 시 불필요한 Row Group을 스킵하는 데 쓰인다. 특히 IN 필터 프루닝에서 효과적이다. 필터 연산 자체가 빨라지면 파일 스캔 비용을 줄인다.
C++: API 추가
| 추가 메서드 | 대상 클래스 | 용도 |
|---|---|---|
ComputeLogicalNullCount() | ChunkedArray | Null 카운트를 논리적으로 계산 (Array/ArrayData에 이미 있던 메서드의 ChunkedArray 버전) |
ToTensor() | Table | 컬럼형 Table을 2D 연속 텐서로 변환 (RecordBatch에 이미 있던 메서드의 Table 버전) |
Table.ToTensor()는 Arrow 테이블을 PyTorch Tensor나 NumPy 배열로 변환할 때 직접 경로를 제공한다. ML 학습 파이프라인에서 피처 테이블을 Arrow로 로드한 뒤 텐서로 변환하는 코드가 단순해진다.
C Data Interface: 변형 버퍼 null 처리 명세
Arrow의 C Data Interface는 언어 경계를 넘어 Arrow 버퍼 포인터를 전달하는 ABI 명세다. 변형 버퍼(variadic buffers)가 null일 수 있다는 점을 25.0.0에서 명시적으로 명세에 포함했다.
변형 버퍼는 가변 길이 바이너리 데이터(문자열, 리스트 등)의 실제 데이터 버퍼다. 특정 조건에서 null 포인터가 전달될 수 있음에도 불구하고 기존 구현 일부가 이를 처리하지 않았다.
이 변경의 주의점: C Data Interface를 통해 Arrow 버퍼를 소비하는 코드(Python ↔ C++ 경계, Rust Arrow ↔ Python 경계 등)는 변형 버퍼 null 가능성을 처리하도록 코드를 확인해야 한다. null 포인터를 역참조하면 크래시가 발생한다.
Arrow Flight SQL: 준비 구문 결과셋 메타데이터
Flight SQL 프로토콜에 서버가 준비 구문(PreparedStatement)이 결과셋을 반환하는지 여부를 클라이언트에게 명시적으로 알릴 수 있는 메커니즘이 추가됐다(GH-49497).
기존에는 ExecuteQuery 유형(결과셋 있음)인지 ExecuteUpdate 유형(행 수 반환)인지 클라이언트가 추론하거나 첫 실행 후 결과를 확인해야 했다. 이제 Prepare 단계에서 서버가 이 정보를 전달한다.
# Flight SQL 준비 구문 실행 흐름 (변경 전)
Client: Prepare("INSERT INTO ...") → PreparedStatementHandle
Client: Execute(handle) → ??? # 결과셋이 있는지 없는지 불명확
# Flight SQL 준비 구문 실행 흐름 (변경 후)
Client: Prepare("INSERT INTO ...") → PreparedStatementHandle + has_result_set=false
Client: ExecuteUpdate(handle) → rows_affected # 명확하게 DML 처리Flight SQL을 구현하는 데이터베이스 엔진(DuckDB, ClickHouse, QuestDB 등)과 클라이언트 드라이버가 이 메타데이터를 활용하면 불필요한 왕복(roundtrip)을 줄인다.
PyArrow: ParquetDataset 단일 파일 경로 처리 복구
pyarrow.parquet.ParquetDataset에 단일 파일 경로를 전달했을 때 발생하는 병합 오류(merge error)를 수정했다. pyarrow.parquet.read_table()에서도 동일 문제가 수정됐다.
import pyarrow.parquet as pq
# 25.0.0에서 정상 작동 (이전 버전에서 오류 발생하던 케이스)
table = pq.read_table("/data/events_2026-07-10.parquet")
dataset = pq.ParquetDataset("/data/single_file.parquet")ADBC 23: Arrow Database Connectivity 현황
Arrow 25.0.0과 함께 확인해야 할 맥락이 ADBC(Arrow Database Connectivity) 생태계다. 2026년 4월 릴리스된 ADBC 23은 API 명세 1.1.x와 함께 다음 데이터베이스 드라이버를 지원한다:
| 드라이버 | 특이사항 |
|---|---|
| Snowflake | 프로덕션 사용 지원 |
| BigQuery | microsecond 타임스탬프 처리 개선, 서비스 계정 impersonation 지원 |
| DuckDB | ADBC를 통한 직접 쿼리 실행 |
| PostgreSQL | 표준 연결 |
| SQLite | 표준 연결 |
| Flight SQL | Arrow Flight SQL 호환 서버 범용 연결 |
| Databricks (Go) | 새로 기여된 Go 드라이버 |
ADBC와 JDBC의 근본적 차이:
| JDBC | ADBC | |
|---|---|---|
| 결과 형식 | Row-oriented (행 단위) | Arrow Columnar (컬럼 단위) |
| 변환 비용 | 읽을 때마다 Arrow 변환 필요 | 변환 없음 |
| 대용량 결과셋 처리 | 메모리 압력 큼 | 스트리밍 Arrow RecordBatch |
| ML/분석 파이프라인 | 추가 변환 필요 | 직접 텐서·DataFrame 전환 |
ADBC가 COPY-level 성능을 단순한 코드로 달성한다는 벤치마크가 실제 운영에서 검증되고 있다.
데이터 플랫폼에서의 실용적 고려사항
Arrow를 사용해야 하는 경우
- 엔진 간 데이터 이동: Spark → DuckDB, Flink → Python ML 파이프라인처럼 엔진을 넘나들 때 Arrow IPC가 직렬화 비용을 없앤다.
- Flight SQL 기반 데이터 게이트웨이: 하나의 Flight SQL 서버가 여러 백엔드 데이터베이스에 대한 고속 쿼리 인터페이스를 제공한다.
- Parquet + PyArrow 파이프라인: 25.0.0에서 수정된 단일 파일 경로 처리, ListView 지원, Bloom filter 성능 등이 직접 영향을 준다.
- ARM64 클라우드 인프라: Graviton 기반 클러스터에서 Arrow를 사용하는 엔진의 필터/집계 성능 개선이 기대된다.
업그레이드 시 주의 사항
- C Data Interface 변형 버퍼 null 처리: Arrow 버퍼를 FFI로 소비하는 커스텀 코드가 있다면 null 가능성을 확인하라.
- PyArrow 버전 고정 해제: 25.0.0에서
ParquetDataset단일 파일 버그가 수정됐으므로, 이 버그를 회피하기 위해 버전을 고정한 프로젝트는 업그레이드를 고려하라.
Open question
- Flight SQL 서버 구현(DuckDB, ClickHouse, QuestDB, InfluxDB IOx 등)이 25.0.0의
has_result_set메타데이터를 얼마나 빠르게 채택할지 명확하지 않다. - ARM64 SVE 동적 디스패치가 특정 Arrow 연산(filter, cast, aggregate)에서 실측 속도 향상이 어느 정도인지 공식 벤치마크가 없다.
- ADBC 1.2 명세(richer metadata, catalog capabilities)의 GA 일정이 미정이다.
References
- Apache Arrow 25.0.0 Release — Apache Arrow Blog
- Apache Arrow Releases — arrow.apache.org
- ADBC: Arrow Database Connectivity — Apache Arrow v25.0.0 docs
- Flight SQL Driver — ADBC 23 documentation
- The State of Apache Arrow in 2026: Ten Years In — AMDataLakehouse
- What is Apache Arrow Flight, Flight SQL & ADBC? — Medium
- The State of Apache Iceberg Catalogs in June 2026 — DEV Community