Skip to main content

概要

ClickHouse は Apache Arrow Flight プロトコルをサポートしています。これは、gRPC 上で Arrow IPC フォーマットを使用し、効率的な列指向データ転送を実現する高性能な RPC フレームワークです。 この実装には Arrow Flight SQL のサポートも含まれており、Flight SQL プロトコルに対応した BI ツールやアプリケーションから ClickHouse に直接クエリできます。 主な機能:
  • SQL クエリを実行し、結果を Apache Arrow フォーマットで取得できます。
  • Arrow フォーマットを使用してテーブルにデータを挿入できます。
  • Flight SQL コマンドを使ってメタデータ (カタログ、スキーマ、テーブル、主キー) をクエリできます。
  • Flight SQL を介してサーバー側のプリペアドステートメントを作成、バインド、実行、クローズできます。
  • Flight SQL アクションを介してセッションと設定を管理できます。
  • TLS 暗号化とユーザー名/パスワード認証。
  • PollFlightInfo による段階的な結果取得。
  • CancelFlightInfo によるクエリのキャンセル。

Arrow Flight Server を有効にする

Arrow Flight Server を有効にするには、ClickHouse サーバー設定に arrowflight_port 設定を追加します。
起動時に、インターフェイスが有効になっていることを示すログメッセージが表示されます。

TLS 設定

Arrow Flight インターフェイスで TLS を有効にするには、以下の設定を行います。
TLS が有効な場合、クライアントは grpc:// ではなく grpc+tls:// 認証スキームを使用して接続する必要があります。

認証

Arrow Flight インターフェイスでは、2 つの認証方法がサポートされています。

基本認証

クライアントは、標準の HTTP Authorization: Basic ヘッダーを介して、ユーザー名とパスワードで認証します。認証に成功すると、サーバーはレスポンスヘッダーで Bearer トークンを返します。

ベアラートークン認証

後続のリクエストでは、基本認証で返されたベアラートークンを Authorization: Bearer <token> ヘッダーで使用できます。トークンは使用するたびに自動的に更新され、有効期限は default_session_timeout サーバー設定 (既定値: 60 秒) に従います。

Python の例

TLS の場合:

セッション管理

Arrow Flight インターフェイスは、カスタム gRPC メタデータヘッダーを介して ClickHouse のセッションをサポートします。
Arrow Flight は HTTP/2 上で gRPC を使用するため、メタデータヘッダー名では大文字と小文字が区別され、ここに示すとおり、正確に小文字で指定する必要があります (例: x-clickhouse-session-id。X-ClickHouse-Session-Id ではありません) 。これは、HTTP/2 のフィールド名には小文字のみを含めることを義務付ける RFC 9113, Section 8.2 で規定されています。これは、ヘッダー名で大文字と小文字が区別されない HTTP/1.1 とは異なります。
セッションを使用すると、SetSessionOptions アクションで永続的な ClickHouse 設定を指定できます (DoAction を参照) 。

サーバー設定リファレンス

サポート対象のRPCメソッド

GetFlightInfo

クエリを実行し、結果のスキーマ、データ取得用チケット付きのエンドポイント、行数、バイト数を含む FlightInfo を返します。 受け取る FlightDescriptor には、次のいずれかを指定できます。
  • PATH descriptor: テーブル名として解釈される単一要素の path です。SELECT * FROM <table> を生成します。
  • CMD descriptor: 生の SQL クエリ文字列、またはシリアライズされた Flight SQL protobuf コマンドです (Flight SQL Commands を参照) 。
クエリは最後まで実行され、結果はサーバー側のチケットに保存されます。データの各 block ごとに個別のエンドポイント/チケットが生成されるため、クライアントはデータを並列に取得できます。

PollFlightInfo

長時間実行されるクエリの結果を、段階的に取得できるようにします。GetFlightInfo のようにクエリ全体の完了を待つのではなく、PollFlightInfo は結果をブロック単位で返します。 最初の呼び出しでクエリの実行が開始され、レスポンスには次の内容が含まれます。
  • その時点で利用可能なデータブロックに対応するエンドポイントを含む FlightInfo
  • 次回のポーリングに使用する FlightDescriptor (さらに結果が返される見込みがある場合)
返されたディスクリプタを使った後続の呼び出しでは、追加のブロックを取得できます。これ以上利用可能なデータがない場合、レスポンスには次のディスクリプタは含まれません。
現在の実装では、データブロックが利用可能になるまで待機し、データがない場合に即座に返すことはありません。

GetSchema

クエリ全体を実行せずに、クエリ結果の Arrow スキーマを返します。GetFlightInfo と同じ種類のディスクリプタを受け付けます。

DoGet

指定された ticket に対応するデータを取得します。次のいずれかを受け付けます。
  • GetFlightInfo または PollFlightInfo が返す ticket。
  • ticket の値として指定する、生の SQL query 文字列。

DoPut

ClickHouse にデータを送信します。FlightDescriptor と Arrow レコードバッチのストリームを受け取ります。 テーブル名による insert (PATH ディスクリプタ) :
SQLによる挿入 (CMDディスクリプタ) :
Flight SQL CommandStatementUpdate による DDL/DML の実行: Flight SQL クライアントは、DDL/DML ステートメント (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 フィールドから抽出されます。また、そのクエリに関連付けられたすべての poll ディスクリプタもキャンセルします。

SetSessionOptions

現在のセッションに対する ClickHouse のサーバー設定を行います。x-clickhouse-session-id ヘッダーでセッション ID が設定されている必要があります。 サポートされる値の型: string、boolean、integer、double、および string list。 設定名が不明な場合は、error INVALID_NAME が返されます。値をパースできない場合は、error INVALID_VALUE が返されます。

GetSessionOptions

現在のセッションの ClickHouse 設定とその値をすべて返します。設定名から文字列値へのマップを返します (内部的には system.settings にクエリします) 。

CreatePreparedStatement

サーバー側のプリペアドステートメントを作成し、ステートメントハンドルを返します。リクエストには、? プレースホルダーを含む SQL クエリテキストが含まれます。 このアクションでは transaction_id はサポートされていません。指定した場合、ClickHouse は NotImplemented エラーを返します。 クエリステートメントの場合、レスポンスには次が含まれることがあります。
  • dataset_schema: 結果セットのスキーマ。
  • parameter_schema: ステートメントパラメータのスキーマ。
有効なクエリでスキーマ推論に失敗した場合でも (たとえば、そのクエリではプレースホルダーを NULL に置き換えることが有効でない場合) 、ClickHouse はプリペアドステートメントを作成し、dataset_schema を含めずにハンドルを返します。 dataset_schema は、Flight SQL 仕様が意図しているとおり、あくまで最善の推測です。仕様では、結果スキーマはパラメータに依存する可能性があり、サーバーは最善の推測を返すべきであり、クライアントはそのスキーマが正確であると想定してはならないとされています。これに依存しないでください。データを表すスキーマを得るには、ステートメントを実行してください。ClickHouse では、次の 2 つの理由により、実際に返されるものと異なる場合があります。
  • 推論では各 ? を NULL に置き換えるため、結果カラムを決定するプレースホルダーは、後でバインドする値ではなくその NULL から型付けされます。SELECT ? AS x では Nothing 型のカラムが推論されますが、5 をバインドすると UInt8 が返されます。SELECT id, name FROM t WHERE id = ? のように、predicate の中でのみ使用されるプレースホルダーでは、結果の型はテーブルから決まるため、この問題は発生しません。
  • Arrow に同等の型が存在しないカラムは、output_format_arrow_unsupported_types から Arrow の型が決まりますが、これは呼び出しごとに、その呼び出しを行うセッションから解決されます。ハンドルは単一のセッションではなくユーザーに属するため、後の呼び出しでは異なる解決結果となり、utf8 と通知されていたところで binary が返される、またはその逆が起こることがあります。プリペアドクエリ自体の中でモードを設定すれば、両方について固定できます。
プリペアドステートメントは、単一のセッションではなく、認証されたユーザーに属します。同じユーザーとして複数のセッションを開いている場合、それらのどのセッションからでも同じステートメントハンドルを実行、再バインド、クローズできます。 他のユーザーは、自分で作成していないステートメントハンドルを実行、バインド、またはクローズできません。 arrowflight.prepared_statements_lifetime_seconds は有効期限の動作を制御します。
  • > 0: 設定された値をステートメントの有効期間として使用します。セッションに紐づくステートメントとセッションレスステートメントの両方で、リクエストのたびに有効期限が更新されます。
  • 0: プリペアドステートメントは自動的に期限切れになりません。
  • -1 (デフォルト): ステートメントがセッション内で作成された場合、その有効期間はそのセッションのタイムアウトに従い、そのセッション内のリクエストごとに更新されます。セッションなしでステートメントが作成された場合、自動的に期限切れにはなりません。
期限切れになったステートメントは削除され、arrowflight.max_prepared_statements_per_user のカウント対象にも含まれなくなります。

ClosePreparedStatement

リクエストに空でないステートメントハンドルが含まれている場合、プリペアドステートメントを閉じ、関連するサーバー側リソースを解放します。 ClickHouse は、ハンドルが空の場合、ClosePreparedStatement による一括クローズもサポートしています。
  • x-clickhouse-session-id が存在する場合、そのセッション内で認証済みユーザーのすべてのプリペアドステートメントを閉じます。
  • セッション ID が存在しない場合、認証済みユーザーのセッションに属さないプリペアドステートメントのみを閉じます。
プリペアドステートメントがセッション内で (x-clickhouse-session-id を介して) 作成された場合、そのセッションが閉じられると、そのステートメントも自動的に閉じられます。

Flight SQL コマンド

CMD ディスクリプタにシリアライズされた Flight SQL protobuf メッセージが含まれている場合、ClickHouse は以下のコマンドを処理します。

GetFlightInfo / GetSchema でサポート

DoPut 経由でサポートされるもの

ClickHouse でサポートされていないもの

これらのコマンドは ClickHouse が提供していない機能に対応しているため、Arrow Flight SQL インターフェイスではサポートされていません。

完全な使用例

Query
Response

データフォーマット

すべてのデータは Apache Arrow IPC フォーマットで転送されます。サポートされるのは Arrow フォーマットのみで、他の ClickHouse フォーマット (例: FORMAT JSON、FORMAT CSV) を指定するとエラーになります。 ClickHouse データ型は、シリアライゼーション時に Arrow の型へマッピングされます。Arrow Flight は常に canonical な Arrow マッピングを使用し、Arrow および ArrowStream 出力フォーマットとは異なり、型の表現方法を変更する output_format_arrow_* 系の設定には従いません。output_format_arrow_string_as_string、output_format_arrow_low_cardinality_as_dictionary、output_format_arrow_date_as_uint16、output_format_arrow_fixed_string_as_fixed_byte_array、および dictionary インデックス関連の設定は、ここでは効果がありません。したがって、同一のクエリであっても Arrow Flight 経由では FORMAT Arrow 経由と異なるスキーマになることがありますが、これは次の 2 つの理由による意図的な設計です。
  • Flight SQL はメタデータ応答のスキーマを固定しています。たとえば CommandGetTables は catalog_name: utf8, db_schema_name: utf8, table_name: utf8 not null, table_type: utf8 not null, table_schema: bytes not null を返す必要があります。session setting によってこれらの utf8 カラムが binary に変わってしまうと、ClickHouse はあらゆる Flight SQL ドライバーに対して非準拠となり、さらに ClickHouse が table_schema 内で公開するテーブルごとのスキーマも変わってしまいます。
  • Flight クライアントは、スキーマとデータを別々の呼び出し (GetFlightInfo または GetSchema、続いて DoGet) で取得します。スキーマを変更し得る設定が存在すると、その間に session が変化した場合に、公開されたスキーマと実際に配信されるストリームが食い違う余地が生まれます。
唯一の例外は、JSON、Dynamic、QBit、AggregateFunction のように Arrow に対応する型がまったく存在しないケースです。基準とすべき canonical なマッピングがないため、ClickHouse は何らかの表現を選択せざるを得ず、output_format_arrow_unsupported_types でどの表現を使うかを指定できます。 AggregateFunction カラムは、text モードであっても Arrow の Binary カラムのままとなる唯一の型です。その text form は生の aggregate state であり valid UTF-8 ではない一方、Arrow の Utf8 カラムは valid UTF-8 を保持しなければならないためです。読みやすい値が必要な場合は finalizeAggregation を使用してください。 同じ理由から、ClickHouse は text の値に含まれるすべての invalid UTF-8 sequence を、Utf8 カラムへ書き込む前に U+FFFD (�) に置き換えます。String を保持する Dynamic はそのバイト列をそのままシリアライズし、その内容は任意のバイトになり得るため、この処理がなければカラムが Arrow 仕様に違反し、厳格なクライアントに拒否される可能性があります。変化するのは、もともと valid text ではない値だけです。バイト列を厳密に保持する必要がある場合は binary モードを使用してください。 output_format_arrow_string_as_string は、FORMAT Arrow の場合も含めてこれらのカラムには適用されません。この設定が制御するのは実際の String および FixedString カラムのみです。したがって、clickhouse.opaque カラムの Arrow 型は、保持している encoding を常に示します。text form であれば Utf8、バイナリ形式であれば Binary です。 これが、AggregateFunction カラムでは問題にならないにもかかわらず、Dynamic に保持された aggregate state が text モードでは情報を失う理由です。カラムは Dynamic として型付けされるため各行が何を保持しているかは分からず、しかもスキーマは値を 1 つも見ない段階で確定するため、その state に専用の Binary カラムを割り当てることはできません。保持したい場合は binary モードを使用してください。Variant は取り得る型を列挙するため、その中に含まれる AggregateFunction は専用の Binary の子を持ち、影響を受けません。 こうしたカラムは、それ以外の点では本物の Utf8/Binary カラムと区別できないため、Arrow の extension 型として宣言されます。フィールドのメタデータには ARROW:extension:name = clickhouse.opaque が保持され、元の ClickHouse 型名は ARROW:extension:metadata に格納されます。extension 名を認識しないクライアントは、Arrow 仕様が定めるとおり、素の storage 型として認識します。nested カラムはそれぞれ自身のフィールドにタグ付けされるため、Array(JSON) ではその子がタグを持ち、Map(JSON, ...) ではそのキーがタグを持ちます。コンテナ自体ではありません。 従来のブール値設定 output_format_arrow_unsupported_types_as_binary も引き続き使用でき、0 の場合は throw、1 の場合は binary と同等です。この設定は、output_format_arrow_unsupported_types がデフォルト値のままの場合にのみ参照されます。

互換性

Arrow Flight インターフェイスは、Arrow Flight または Arrow Flight SQL プロトコルをサポートするあらゆるクライアントやツールと互換性があります。具体的には、次のようなものが含まれます。
  • Python (pyarrow)
  • Java (org.apache.arrow.flight)
  • C++ (arrow::flight)
  • Go (apache/arrow/go)
  • ADBC (Arrow Database Connectivity) ドライバー
  • DBeaver など、Flight SQL をサポートするその他のツール
お使いのツール向けにネイティブの ClickHouse コネクタ (例: JDBC、ODBC、ネイティブプロトコル) が利用できる場合は、パフォーマンス上の理由やフォーマット互換性のために Arrow Flight が特に必要でない限り、そちらを優先して使用してください。

クライアント側のArrowFlight機能

ClickHouseは、外部のArrow Flightサーバーからデータを読み取るFlightクライアントとしても動作します。詳しくは、以下を参照してください。

関連項目

最終更新日 2026年9月26日