LLM WikiAccess-protected knowledge portal

WIKI

Apache Arrow Flight SQL: 컬럼형 고성능 DB 연결의 원리와 운영 패턴

요약 데이터베이스에서 대량의 데이터를 빠르게 꺼내야 할 때 JDBC나 ODBC는 숨겨진 병목을 만든다. 행 row 을 하나씩 직렬화해 네트워크로 보내고, 클라이언트에서 다시 역직렬화하는 구조가 열 지향 columnar 분석 엔진과 근본적으로 맞지 않기 때문이다. Apache Arrow Flight SQL 은 이 문제를 해결하기 위해 만들어진 고성능 SQL 인터페이스다. Arrow 형식의 컬럼 데이터를 gRPC 위에서 직접 전송

경로human/study/content/database-frontier/122-arrow-flight-sql-columnar-db-connectivity.md
카테고리Study
태그#arrow #columnar #connectivity #flight #mysql #sql #study

요약

데이터베이스에서 대량의 데이터를 빠르게 꺼내야 할 때 JDBC나 ODBC는 숨겨진 병목을 만든다. 행(row)을 하나씩 직렬화해 네트워크로 보내고, 클라이언트에서 다시 역직렬화하는 구조가 열 지향(columnar) 분석 엔진과 근본적으로 맞지 않기 때문이다.

Apache Arrow Flight SQL은 이 문제를 해결하기 위해 만들어진 고성능 SQL 인터페이스다. Arrow 형식의 컬럼 데이터를 gRPC 위에서 직접 전송해 직렬화·역직렬화 오버헤드를 없앤다. StarRocks, DuckDB, Dremio, Snowflake, PostgreSQL 어댑터 등 주요 분석 데이터베이스들이 이를 지원하거나 도입 중이다.

이 글은 Arrow Flight와 Flight SQL의 구조, ADBC 클라이언트 인터페이스, 실제 성능 특성, 그리고 데이터 플랫폼 엔지니어가 알아야 할 운영 지점을 다룬다.


배경: JDBC/ODBC의 구조적 한계

전통적인 데이터베이스 클라이언트-서버 프로토콜(JDBC, ODBC)의 데이터 흐름을 따라가보자.

DB (컬럼 저장) → [행 변환] → [직렬화: 텍스트/바이너리] → [네트워크] → [역직렬화] → [열 변환] → 분석 엔진

각 단계에서 비용이 발생한다:

  1. 행 변환: DB 내부가 컬럼 저장이더라도 드라이버 수준에서 행 단위로 조립한다.
  2. 직렬화: 각 값을 네트워크 전송 가능한 형태로 변환한다 (타입 정보 포함).
  3. 역직렬화: 클라이언트에서 다시 원래 타입으로 복원한다.
  4. 열 변환: Pandas, Spark, Arrow 등이 컬럼 형태로 다시 재배치한다.

1GB 데이터를 JDBC로 꺼내면 실제 네트워크 페이로드가 3~5GB에 달하는 경우가 흔하다. CPU 사이클의 상당 부분이 데이터 이동 자체에 소모된다.


Arrow Flight: 고속 컬럼 전송 레이어

Apache Arrow Flight는 gRPC 위에서 Arrow RecordBatch를 스트리밍 전송하는 프레임워크다. 2019년 Apache Arrow 프로젝트에서 공개됐다.

핵심 설계 원칙

1. Arrow IPC 형식: 네트워크 페이로드 = Arrow 컬럼 버퍼 그 자체
2. 제로카피(zero-copy): 수신측 Arrow 라이브러리가 버퍼를 역직렬화 없이 직접 사용
3. gRPC 스트리밍: 양방향 스트림으로 대량 데이터 파이프라인 구성
4. 병렬 엔드포인트: 단일 쿼리를 여러 스트림으로 분산 전송(파티션 병렬)

기존 프로토콜 대비 제거되는 변환:

단계JDBCArrow Flight
DB 내부 → 전송 형식행 변환 + 직렬화Arrow IPC 직접 사용
네트워크텍스트/바이너리 행Arrow 컬럼 버퍼
클라이언트 수신역직렬화제로카피 Arrow 접근
분석 엔진 투입컬럼 재변환Arrow 바로 사용

Arrow Flight RPC 핵심 메서드

ListFlights   — 서버에서 사용 가능한 데이터 스트림 목록 조회
GetFlightInfo — 특정 데이터(쿼리 결과 등)의 메타데이터와 엔드포인트 목록 획득
DoGet         — 서버에서 클라이언트로 데이터 스트림 수신
DoPut         — 클라이언트에서 서버로 데이터 스트림 전송
DoAction      — 서버에서 임의 액션 실행(커스텀 커맨드)

Arrow Flight SQL: SQL 의미론 추가

Arrow Flight SQL은 Flight RPC 위에 SQL 인터페이스를 정의한 프로토콜 확장이다. 2022년 Apache Arrow에서 공개됐다.

Apache Arrow Flight SQL 아키텍처 클라이언트 ADBC Python / Java 통합 클라이언트 인터페이스 Arrow Flight SQL Driver SQL → FlightSQL 프로토콜 gRPC 클라이언트 HTTP/2 스트리밍 수신 데이터: Arrow RecordBatch 컬럼 버퍼 그대로 수신 Pandas / Polars / Spark 제로카피로 바로 투입 DuckDB / PyArrow Arrow 쿼리 직접 실행 네트워크 gRPC / HTTP/2 Arrow IPC 컬럼 버퍼 직렬화 없음 병렬 스트림 파티션별 분산 전송 가능 SQL 전송 결과 수신 Flight SQL 서버 (데이터베이스) Flight SQL 서버 구현 CommandStatementQuery / CommandGetTables 등 핸들러 SQL 파서 / 옵티마이저 SQL 쿼리 실행 → Arrow RecordBatch 생성 지원 DB 예시: StarRocks OLAP 벌크 추출 최적화 DuckDB sqlflite / porter 서버 Dremio 첫 Flight SQL 도입 사례 PostgreSQL 어댑터 pg_arrow_flight_sql Snowflake ADBC 드라이버 지원 Influx/TSDB Flight SQL 네이티브 병렬 스트림 (Partition Parallelism) GetFlightInfo → 여러 Endpoint 반환 클라이언트가 각 Endpoint에 병렬 DoGet → 분산 수신 예: 10억 행 쿼리 → Endpoint 16개 → 16개 스트림 동시 수신
Arrow Flight SQL 아키텍처: 클라이언트에서 DB까지의 데이터 흐름

Flight SQL의 SQL 프로토콜 동작

1. PreparedStatementQuery: SQL 문자열 → 서버가 실행계획 수립 → StatementHandle 반환
2. GetFlightInfo:          StatementHandle → Endpoint 목록(파티션) 반환
3. DoGet:                  각 Endpoint → Arrow RecordBatch 스트림 수신
4. (선택) DoPut:           클라이언트 → 서버로 Arrow 배치 업로드 (데이터 적재)

Flight SQL은 또한 메타데이터 조회(CommandGetTables, CommandGetColumns, CommandGetPrimaryKeys)도 Arrow 형식으로 반환해 스키마 탐색도 빠르다.


ADBC: 통합 클라이언트 API

ADBC(Arrow Database Connectivity)는 Arrow Flight SQL 등 Arrow 네이티브 DB에 접근하는 통합 클라이언트 API다. JDBC가 여러 DB에 대한 단일 Java API를 제공하듯, ADBC는 Arrow 기반 DB 연결을 위한 표준 인터페이스를 제공한다.

Python 예시

import adbc_driver_flightsql.dbapi as dbapi

# StarRocks 또는 Dremio Flight SQL 서버에 연결
conn = dbapi.connect(
    "grpc+tcp://starrocks-host:9090",
    db_kwargs={
        "username": "user",
        "password": "pass",
    }
)

with conn.cursor() as cursor:
    cursor.execute("SELECT * FROM large_table WHERE dt = '2026-08-19'")

    # Arrow RecordBatch로 직접 수신 — 역직렬화 없음
    arrow_table = cursor.fetch_arrow_table()

    # Pandas로 변환 (zero-copy 가능)
    df = arrow_table.to_pandas(zero_copy_only=True)

ADBC 24(2026-07-28 출시)는 PostgreSQL, SQLite, FlightSQL, BigQuery, Snowflake, DuckDB 드라이버를 포함한다.


실제 성능 특성

StarRocks 벤치마크 (공식 문서 기준)

StarRocks에서 Arrow Flight SQL을 통해 대용량 데이터를 추출할 때:

Voltron Data 벤치마크 (Flight SQL vs JDBC)

병렬 스트림의 실질 효과

단일 스트림: 네트워크 1 연결 → 1 GbE = 최대 125 MB/s 수신
병렬 16 스트림: 네트워크 16 연결 → 이론적 최대 16× (네트워크 한계까지)

단, 서버가 병렬 Endpoint를 지원해야 한다. DuckDB, Dremio는 지원. PostgreSQL 어댑터는 현재 단일 Endpoint.


운영 고려사항

언제 Flight SQL이 유리한가

상황Flight SQLJDBC/ODBC
대규모 분석 쿼리 (수억 행)✅ 유리병목 발생
ML 피처 스토어 데이터 추출✅ Arrow 직접 투입변환 오버헤드
ETL 배치 파이프라인✅ 유리보통
OLTP 포인트 쿼리 (수백 행)오버헤드 있음✅ 적합
기존 Java/BI 도구 연동어댑터 필요✅ 직접 지원
리얼타임 BI 쿼리 (복잡한 조회)케이스별 다름✅ 통합 용이

TLS 및 인증

gRPC 위에서 동작하므로 TLS 설정이 필수다. StarRocks, Dremio 모두 JWT 또는 기본 인증을 Flight SQL 메타데이터로 전달하는 방식을 사용한다.

conn = dbapi.connect(
    "grpc+tls://host:9090",  # TLS 강제
    db_kwargs={
        "adbc.flight.sql.client_option.tls_root_certs": open("ca.crt").read(),
        "username": "user",
        "password": "pass",
    }
)

스키마 진화 주의점

Arrow IPC 형식은 스키마를 RecordBatch에 포함한다. 서버가 컬럼을 추가하거나 타입을 변경하면 기존 클라이언트가 실패할 수 있다. ADBC는 fetch_record_batch_reader()로 스트림 방식 처리를 권장한다.

연결 풀 관리

gRPC 채널은 HTTP/2 멀티플렉싱을 사용하므로 JDBC처럼 많은 연결이 필요하지 않다. 채널 하나로 다수의 동시 스트림을 처리할 수 있다. 단, 매 쿼리마다 새 채널을 만들면 TLS 핸드셰이크 비용이 누적된다.

# 채널 재사용 — 연결 풀 역할
conn = dbapi.connect("grpc+tls://host:9090", db_kwargs={...})
# conn을 세션 수준에서 유지, 쿼리마다 재사용

모니터링 포인트


도입 로드맵

1단계: 기존 JDBC 쿼리 중 대용량 데이터 추출 작업 식별
       → JDBC 대비 병목이 확인된 파이프라인 선정

2단계: 해당 DB의 Flight SQL 지원 여부 확인
       → StarRocks, Dremio, Snowflake: 기본 지원
       → PostgreSQL: pg_arrow_flight_sql 어댑터 설치
       → MySQL: 직접 지원 없음 (Trino 경유 가능)

3단계: adbc_driver_flightsql 설치 및 프로토타입
       pip install adbc-driver-flightsql adbc-driver-manager

4단계: 성능 측정: JDBC 대비 추출 시간, 메모리 사용량 비교

5단계: 프로덕션 전환 — TLS, 인증, 재시도, 모니터링 추가

체크리스트


References