개요
- SQL 쿼리를 실행하고 결과를 Apache Arrow 형식으로 가져옵니다.
- Arrow 형식을 사용해 테이블에 데이터를 삽입합니다.
- Flight SQL 명령을 통해 메타데이터(카탈로그, 스키마, 테이블, 프라이머리 키)를 쿼리합니다.
- Flight SQL을 통해 서버 측 prepared statement를 생성, 바인드, 실행, 종료합니다.
- Flight SQL 작업을 통해 세션 및 설정을 관리합니다.
- TLS 암호화와 사용자 이름/비밀번호 인증을 지원합니다.
PollFlightInfo를 통한 점진적 결과 조회.CancelFlightInfo를 통한 쿼리 취소.
Arrow Flight 서버 활성화
arrowflight_port 설정을 추가합니다:
TLS 구성
grpc:// 대신 grpc+tls:// 스킴으로 연결해야 합니다.
인증
기본 인증
Authorization: Basic 헤더를 사용해 사용자 이름과 비밀번호로 인증합니다. 인증에 성공하면 server는 응답 헤더에 Bearer 토큰을 반환합니다.
Bearer 토큰 인증
Authorization: Bearer <token> 헤더를 통해 사용할 수 있습니다. 이 토큰은 사용할 때마다 자동으로 갱신되며, default_session_timeout 서버 설정에 따라 만료됩니다(기본값: 60초).
Python 예시
세션 관리
| Header | Description |
|---|---|
x-clickhouse-session-id | 세션 식별자입니다. 지정하면 여러 요청이 동일한 세션 상태(임시 테이블, 설정)를 공유합니다. |
x-clickhouse-session-timeout | 초 단위 세션 timeout입니다. max_session_timeout을 초과하면 안 됩니다. |
x-clickhouse-session-check | 세션을 생성하지 않고 존재 여부만 확인하려면 1로 설정합니다. |
x-clickhouse-session-close | 요청이 완료된 후 세션을 닫으려면 1로 설정합니다. server config에서 enable_arrow_close_session이 true로 설정되어 있어야 합니다. |
Arrow Flight는 HTTP/2 기반 gRPC를 사용하므로 메타데이터 헤더 이름은 대소문자를 구분하며, 아래에 표시된 그대로 반드시 소문자로 지정해야 합니다(예:
x-clickhouse-session-id, X-ClickHouse-Session-Id 아님). 이는 HTTP/2 필드 이름에 소문자만 포함되어야 한다고 규정한 RFC 9113, Section 8.2의 요구 사항입니다. 이는 헤더 이름이 대소문자를 구분하지 않는 HTTP/1.1과 다릅니다.SetSessionOptions action을 통해 ClickHouse 설정을 지속적으로 적용할 수 있습니다(DoAction 참조).
서버 구성 참고
| 설정 | 기본값 | 설명 |
|---|---|---|
arrowflight_port | — | Arrow Flight 서버용 포트입니다. 이 설정을 지정한 경우에만 서버가 시작됩니다. |
arrowflight.enable_ssl | false | TLS 암호화를 활성화합니다. |
arrowflight.ssl_cert_file | — | TLS 인증서 파일 경로입니다. TLS가 활성화된 경우 필요합니다. |
arrowflight.ssl_key_file | — | TLS 개인 키 파일 경로입니다. TLS가 활성화된 경우 필요합니다. |
arrowflight.tickets_lifetime_seconds | 600 | Flight 티켓이 만료되어 정리되기까지의 시간(초)입니다. 티켓 자동 만료를 비활성화하려면 0으로 설정합니다. |
arrowflight.cancel_ticket_after_do_get | false | true이면 DoGet에서 티켓을 사용한 직후 티켓이 취소되어 메모리가 해제됩니다. |
arrowflight.poll_descriptors_lifetime_seconds | 600 | 폴링 디스크립터가 만료되기까지의 시간(초)입니다. 자동 만료를 비활성화하려면 0으로 설정합니다. |
arrowflight.cancel_flight_descriptor_after_poll_flight_info | false | true이면 폴링 디스크립터가 PollFlightInfo에서 사용된 후 취소됩니다. |
arrowflight.max_prepared_statements_per_user | 100 | 사용자당 열어 둘 수 있는 prepared statement의 최대 개수입니다. 제한을 비활성화하려면 0으로 설정합니다. |
arrowflight.prepared_statements_lifetime_seconds | -1 | prepared statement 수명 모드입니다. > 0: 이 값을 수명으로 사용하고, 세션에 바인딩된 SQL 문과 세션에 바인딩되지 않은 SQL 문 모두에 대해 각 요청마다 만료 시점을 갱신합니다. 0: 자동 만료를 비활성화합니다. -1: 세션에 바인딩된 SQL 문의 경우 세션 타임아웃을 수명으로 사용하고 각 요청마다 이를 갱신합니다. 세션에 바인딩되지 않은 SQL 문은 자동으로 만료되지 않습니다. |
enable_arrow_close_session | true | 클라이언트가 x-clickhouse-session-close 헤더를 통해 세션을 종료할 수 있도록 허용합니다. |
default_session_timeout | 60 | 기본 세션 타임아웃(초)입니다. Bearer token 만료에도 적용됩니다. |
max_session_timeout | 3600 | 허용되는 최대 세션 타임아웃(초)입니다. |
지원되는 RPC 메서드
GetFlightInfo
FlightInfo를 반환합니다.
다음 중 하나일 수 있는 FlightDescriptor를 받습니다:
- PATH 디스크립터: table 이름으로 해석되는 단일 구성 요소 경로입니다.
SELECT * FROM <table>를 생성합니다. - CMD 디스크립터: 원시 SQL 쿼리 문자열 또는 직렬화된 Flight SQL protobuf 명령입니다(Flight SQL Commands 참조).
PollFlightInfo
GetFlightInfo와 달리, PollFlightInfo는 결과를 블록 단위로 반환합니다.
첫 번째 호출 시 쿼리 실행이 시작됩니다. 응답에는 다음이 포함됩니다:
- 현재까지 사용 가능한 데이터 블록의 endpoint가 포함된
FlightInfo - 다음 폴링에 사용할
FlightDescriptor(추가 결과가 예상되는 경우)
현재 구현은 데이터 블록을 사용할 수 있을 때까지 대기하며, 데이터 없이 즉시 반환하지는 않습니다.
GetSchema
GetFlightInfo와 동일한 디스크립터 유형을 지원합니다.
DoGet
GetFlightInfo또는PollFlightInfo에서 반환된 티켓- 티켓 값으로 전달되는 원시 SQL 쿼리 문자열
DoPut
FlightDescriptor와 Arrow 레코드 배치 스트림을 인수로 받습니다.
테이블 이름으로 삽입 (PATH 디스크립터):
CommandStatementUpdate를 통한 DDL/DML 실행:
Flight SQL 클라이언트는 DDL/DML SQL 문(CREATE, INSERT, ALTER 등)을 실행할 때 CommandStatementUpdate를 사용합니다. 응답에는 영향을 받은 행 수가 포함됩니다.
Flight SQL CommandStatementIngest를 통한 대량 수집:
기존 테이블에 데이터를 추가하는 작업만 지원됩니다(TABLE_NOT_EXIST_OPTION_FAIL + TABLE_EXISTS_OPTION_APPEND). 이 명령에서는 카탈로그와 임시 테이블을 지원하지 않습니다.
transaction_id는 CommandStatementUpdate와 CommandStatementIngest 모두에서 지원되지 않습니다. 이를 제공하면 ClickHouse는 NotImplemented 오류를 반환합니다.
데이터 전송에는
Arrow 형식만 허용됩니다. SQL에서 다른 포맷을 지정하면(예: FORMAT JSON) 오류가 발생합니다.DoAction
CancelFlightInfo
FlightInfo와 연결된 실행 중인 쿼리를 취소합니다. 쿼리 ID는 FlightInfo의 app_metadata 필드에서 추출됩니다. 또한 해당 쿼리와 연결된 모든 폴링 디스크립터도 취소합니다.
SetSessionOptions
x-clickhouse-session-id 헤더를 통해 세션 ID가 설정되어 있어야 합니다.
지원되는 값 타입: string, boolean, integer, double, string list입니다.
설정 이름을 인식할 수 없으면 오류 INVALID_NAME이 반환됩니다. 값을 파싱할 수 없으면 오류 INVALID_VALUE가 반환됩니다.
GetSessionOptions
system.settings를 쿼리합니다).
CreatePreparedStatement
? 플레이스홀더가 포함된 SQL 쿼리 텍스트가 들어 있습니다.
이 작업에서는 transaction_id를 지원하지 않습니다. 이를 제공하면 ClickHouse는 NotImplemented 오류를 반환합니다.
쿼리 SQL 문의 경우 응답에 다음이 포함될 수 있습니다:
dataset_schema: result set의 스키마parameter_schema: SQL 문 매개변수의 스키마
NULL로 대체하는 것이 해당 쿼리에서 유효하지 않은 경우) ClickHouse는 여전히 prepared statement를 생성하고 dataset_schema 없이 handle을 반환합니다.
Prepared statements는 단일 세션이 아니라 인증된 사용자가 소유합니다. 동일한 사용자로 여러 세션을 열면 그 세션들 중 어느 세션에서든 동일한 statement handle을 실행, 다시 바인드, 종료할 수 있습니다.
다른 사용자는 자신이 생성하지 않은 statement handle을 실행, 바인드 또는 종료할 수 없습니다.
arrowflight.prepared_statements_lifetime_seconds는 만료 동작을 제어합니다:
> 0: 구성된 값을 statement의 수명으로 사용합니다. 세션에 바인딩된 statement와 세션이 없는 statement 모두에서 각 요청 시 만료 시간이 갱신됩니다.0: prepared statements는 자동으로 만료되지 않습니다.-1(기본값): statement가 세션에서 생성되면 수명은 해당 세션 timeout을 따르며, 그 세션의 각 요청 시 갱신됩니다. statement가 세션 없이 생성되면 자동으로 만료되지 않습니다.
arrowflight.max_prepared_statements_per_user에 포함되지 않습니다.
ClosePreparedStatement
ClosePreparedStatement를 사용한 일괄 종료도 지원합니다.
x-clickhouse-session-id가 있으면 해당 세션에서 인증된 사용자의 모든 prepared statement를 닫습니다.- 세션 ID가 없으면 인증된 사용자의 세션 없는 prepared statement만 닫습니다.
x-clickhouse-session-id를 통해)에서 생성된 경우, 해당 세션이 종료될 때 자동으로 함께 닫힙니다.
Flight SQL 명령
CMD 디스크립터에 직렬화된 Flight SQL protobuf 메시지가 포함된 경우, ClickHouse는 다음 명령을 처리합니다:
GetFlightInfo / GetSchema에서 지원
| Command | Description |
|---|---|
CommandStatementQuery | 임의의 SQL 쿼리를 실행합니다. transaction_id는 지원되지 않습니다. |
CommandGetSqlInfo | 서버 메타데이터(이름, 버전, Arrow 버전, capability)를 가져옵니다. |
CommandGetCatalogs | 카탈로그를 나열합니다. 빈 결과를 반환합니다(ClickHouse는 카탈로그를 사용하지 않습니다). |
CommandGetDbSchemas | 데이터베이스를 나열합니다. 선택적 db_schema_filter_pattern(SQL LIKE 패턴)을 지원합니다. |
CommandGetTables | 테이블을 나열합니다. 스키마, 테이블 이름, 테이블 타입, 선택적 스키마 포함 여부에 대한 필터를 지원합니다. |
CommandGetTableTypes | 테이블 엔진 타입을 나열합니다(system.table_engines 기준). |
CommandGetPrimaryKeys | 지정된 테이블의 프라이머리 키 컬럼을 가져옵니다. |
CommandPreparedStatementQuery | 핸들로 준비된 SELECT 스타일 구문을 실행합니다. |
DoPut을 통해 지원됩니다
| Command | Description |
|---|---|
CommandStatementUpdate | DDL/DML 문(CREATE, INSERT, ALTER 등)을 실행합니다. 영향을 받은 행 수를 반환합니다. transaction_id는 지원되지 않습니다. |
CommandStatementIngest | 기존 테이블에 Arrow 데이터를 대량 삽입합니다. append 모드만 지원됩니다. transaction_id는 지원되지 않습니다. |
CommandPreparedStatementQuery | DoPut으로 전송할 때 prepared statement의 매개변수 값을 바인딩한 뒤, statement handle이 포함된 DoPutPreparedStatementResult를 반환합니다. 매개변수 집합은 1개(행 1개)만 허용되며, 바인딩된 값의 개수는 ? placeholder의 개수와 정확히 일치해야 합니다. |
CommandPreparedStatementUpdate | handle로 prepared DDL/DML 문을 실행하고 영향을 받은 행 수를 반환합니다. |
ClickHouse에서 지원되지 않음
| Command | Reason |
|---|---|
CommandGetCrossReference | ClickHouse는 관계형 데이터베이스가 아니며 외래 키 제약 조건을 구현하지 않으므로 교차 참조 메타데이터를 제공하지 않습니다. |
CommandGetExportedKeys | ClickHouse는 관계형 데이터베이스가 아니며 외래 키 제약 조건을 구현하지 않으므로 내보낸 키 메타데이터를 제공하지 않습니다. |
CommandGetImportedKeys | ClickHouse는 관계형 데이터베이스가 아니며 외래 키 제약 조건을 구현하지 않으므로 가져온 키 메타데이터를 제공하지 않습니다. |
CommandStatementSubstraitPlan | ClickHouse는 Substrait plan을 지원하지 않습니다. |
전체 예시
Query
Response
데이터 포맷
Arrow 형식만 지원되며, 다른 ClickHouse 포맷(예: FORMAT JSON, FORMAT CSV)을 지정하면 오류가 발생합니다.
직렬화 시 ClickHouse 데이터 타입은 Arrow 타입으로 매핑됩니다. 설정 output_format_arrow_unsupported_types_as_binary는 지원되지 않는 ClickHouse 타입을 바이너리 blob으로 직렬화할지 여부를 제어합니다.
호환성
- Python (
pyarrow) - Java (
org.apache.arrow.flight) - C++ (
arrow::flight) - Go (
apache/arrow/go) - ADBC (Arrow Database Connectivity) 드라이버
- DBeaver 및 Flight SQL을 지원하는 기타 도구