LLM WikiAccess-protected knowledge portal
← 스터디 홈
122편 · 약 16분

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

요약

데이터베이스에서 대량의 데이터를 빠르게 꺼내야 할 때 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을 통해 대용량 데이터를 추출할 때:

  • JDBC 대비: 직렬화·역직렬화 제거로 네트워크 페이로드 40~60% 감소
  • 행-열 변환 비용: 컬럼 엔진이 Arrow 형식 그대로 전송해 추가 변환 없음
  • 병렬 스트림: 단일 쿼리를 다수 스트림으로 분산해 네트워크 포화 가능

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

  • Flight SQL ADBC가 JDBC 대비 2~5배 빠른 데이터 추출 처리량
  • 대용량 데이터일수록 격차 확대 (직렬화 비용의 절대량 차이)
  • 소용량(< 수만 행): gRPC 연결 오버헤드로 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을 세션 수준에서 유지, 쿼리마다 재사용

모니터링 포인트

  • gRPC 스트림 오류율: DoGet 실패가 증가하면 서버 과부하 또는 네트워크 불안정
  • RecordBatch 크기: 너무 작으면(< 수천 행) 오버헤드 비율이 높음, 서버 측 배치 크기 조정
  • 연결 지연: gRPC 채널 첫 생성 시 TLS 핸드셰이크가 추가됨, 커넥션 워밍이 필요한지 판단
  • 병렬 스트림 수: 실제 네트워크 처리량 포화 여부 확인

도입 로드맵

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, 인증, 재시도, 모니터링 추가

체크리스트

  • [ ] 대용량 데이터 추출 파이프라인에서 Flight SQL 적용 가능한 DB를 파악했는가
  • [ ] 대상 DB가 Flight SQL 서버를 지원하는지 (또는 어댑터 설치 필요 여부) 확인했는가
  • [ ] ADBC Python/Java 드라이버를 설치하고 기본 연결을 검증했는가
  • [ ] TLS 인증서와 인증 방식(Basic, JWT)을 구성했는가
  • [ ] 단일 스트림과 병렬 스트림 성능을 측정하고 실제 개선을 확인했는가
  • [ ] RecordBatch 크기를 워크로드에 맞게 조정했는가 (너무 작으면 오버헤드)
  • [ ] gRPC 채널을 세션 수준에서 재사용하도록 코드를 구성했는가
  • [ ] 스키마 변경 시 클라이언트 호환성을 사전에 검토했는가

References

  • Apache Arrow Flight SQL 공식 스펙: https://arrow.apache.org/docs/format/FlightSql.html
  • Introducing Arrow Flight SQL 블로그 (Apache Arrow): https://arrow.apache.org/blog/2022/02/16/introducing-arrow-flight-sql/
  • Apache Arrow ADBC 24 릴리스: https://arrow.apache.org/blog/
  • StarRocks Arrow Flight SQL 문서: https://docs.starrocks.io/docs/unloading/arrow_flight/
  • Voltron Data Flight SQL vs JDBC 벤치마크: https://github.com/voltrondata/flight-sql-adbc-vs-jdbc
  • PostgreSQL Arrow Flight SQL 어댑터 0.1.0: https://www.postgresql.org/about/news/apache-arrow-flight-sql-adapter-for-postgresql-010-2716/
  • P99 CONF High-speed Database Throughput 발표: https://www.p99conf.io/session/high-speed-database-throughput-using-apache-arrow-flight-sql/
  • Dipankar Mazumdar: Arrow Flight, Flight SQL, ADBC 개요: https://dipankar-tnt.medium.com/what-is-apache-arrow-flight-flight-sql-adbc-a076511122ac