Skip to main content

クライアント (V1)

DBサーバとそのプロトコルを介して通信するためのJavaクライアントライブラリです。現在の実装ではHTTPインターフェースのみをサポートしています。このライブラリは、サーバにリクエストを送信するための独自のAPIを提供します。

注意: このコンポーネントは間もなく非推奨になります。

セットアップ

<!-- https://mvnrepository.com/artifact/com.clickhouse/clickhouse-http-client -->
<dependency>
<groupId>com.clickhouse</groupId>
<artifactId>clickhouse-http-client</artifactId>
<version>0.6.5</version>
</dependency>

バージョン 0.5.0 以降、ドライバーは新しいクライアントHTTPライブラリを使用し、それを依存関係として追加する必要があります。

<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5 -->
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.3.1</version>
</dependency>

初期化

接続URL形式: protocol://host[:port][/database][?param[=value][&param[=value]][#tag[,tag]], 例として:

  • http://localhost:8443?ssl=true&sslmode=NONE
  • https://(https://explorer@play.clickhouse.com:443

単一ノードに接続:

ClickHouseNode server = ClickHouseNode.of("http://localhost:8123/default?compress=0");

複数ノードのクラスタに接続:

ClickHouseNodes servers = ClickHouseNodes.of(
"jdbc:ch:http://server1.domain,server2.domain,server3.domain/my_db"
+ "?load_balancing_policy=random&health_check_interval=5000&failover=2");

クエリAPI

try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
ClickHouseResponse response = client.read(servers)
.format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
.query("select * from numbers limit :limit")
.params(1000)
.executeAndWait()) {
ClickHouseResponseSummary summary = response.getSummary();
long totalRows = summary.getTotalRowsToRead();
}

ストリーミングクエリAPI

try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
ClickHouseResponse response = client.read(servers)
.format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
.query("select * from numbers limit :limit")
.params(1000)
.executeAndWait()) {
for (ClickHouseRecord r : response.records()) {
int num = r.getValue(0).asInteger();
// 型変換
String str = r.getValue(0).asString();
LocalDate date = r.getValue(0).asDate();
}
}

リポジトリ内の完全なコード例を参照してください。

挿入API


try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
ClickHouseResponse response = client.read(servers).write()
.format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
.query("insert into my_table select c2, c3 from input('c1 UInt8, c2 String, c3 Int32')")
.data(myInputStream) // `myInputStream` はRowBinary形式のデータソース
.executeAndWait()) {
ClickHouseResponseSummary summary = response.getSummary();
summary.getWrittenRows();
}

リポジトリ内の完全なコード例を参照してください。

RowBinary エンコーディング

RowBinary形式はそのページに記述されています。

コードの例があります。

機能

圧縮

このクライアントはデフォルトでLZ4圧縮を使用します。それには以下の依存関係が必要です。

<!-- https://mvnrepository.com/artifact/org.lz4/lz4-java -->
<dependency>
<groupId>org.lz4</groupId>
<artifactId>lz4-java</artifactId>
<version>1.8.0</version>
</dependency>

代わりにgzipを使用したい場合は、接続URLにcompress_algorithm=gzipを設定してください。

また、数通りの方法で圧縮を無効にすることができます。

  1. 接続URLに compress=0 を設定して無効にする: http://localhost:8123/default?compress=0
  2. クライアント設定経由で無効にする:
ClickHouseClient client = ClickHouseClient.builder()
.config(new ClickHouseConfig(Map.of(ClickHouseClientOption.COMPRESS, false)))
.nodeSelector(ClickHouseNodeSelector.of(ClickHouseProtocol.HTTP))
.build();

異なる圧縮オプションについての詳細は、圧縮ドキュメントを参照してください。

複数クエリ

同じセッション内で、複数のクエリを一つづつワーカースレッドで実行します:

CompletableFuture<List<ClickHouseResponseSummary>> future = ClickHouseClient.send(servers.apply(servers.getNodeSelector()),
"create database if not exists my_base",
"use my_base",
"create table if not exists test_table(s String) engine=Memory",
"insert into test_table values('1')('2')('3')",
"select * from test_table limit 1",
"truncate table test_table",
"drop table if exists test_table");
List<ClickHouseResponseSummary> results = future.get();

名前付きパラメータ

パラメータリストの位置に依存する代わりに、名前でパラメータを渡すことができます。この機能はparams機能を使用することで利用可能になります。

try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
ClickHouseResponse response = client.read(servers)
.format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
.query("select * from my_table where name=:name limit :limit")
.params("Ben", 1000)
.executeAndWait()) {
//...
}
}
パラメータ

String型を含む全てのparamsシグネチャ(String, String[], Map<String, String>)は、渡されるキーが有効なClickHouseのSQL文字列であると仮定します。たとえば:

try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
ClickHouseResponse response = client.read(servers)
.format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
.query("select * from my_table where name=:name")
.params(Map.of("name","'Ben'"))
.executeAndWait()) {
//...
}
}

Stringオブジェクトを手動でClickHouse SQLに解析したくない場合は、com.clickhouse.dataにあるヘルパー関数ClickHouseValues.convertToSqlExpressionを使用できます:

try (ClickHouseClient client = ClickHouseClient.newInstance(ClickHouseProtocol.HTTP);
ClickHouseResponse response = client.read(servers)
.format(ClickHouseFormat.RowBinaryWithNamesAndTypes)
.query("select * from my_table where name=:name")
.params(Map.of("name", ClickHouseValues.convertToSqlExpression("Ben's")))
.executeAndWait()) {
//...
}
}

上記の例では、ClickHouseValues.convertToSqlExpressionが内部のシングルクォーテーションをエスケープし、変数を有効なシングルクォーテーションで囲みます。

他の型、例えばIntegerUUIDArrayEnumなどは、params内で自動的に変換されます。

ノード検出

Javaクライアントは、ClickHouseノードを自動で検出する機能を提供します。自動検出はデフォルトで無効になっています。手動で有効にするには、auto_discoverytrueに設定します:

properties.setProperty("auto_discovery", "true");

または接続URL内で:

jdbc:ch://my-server/system?auto_discovery=true

自動検出が有効な場合、接続URL内に全てのClickHouseノードを指定する必要はありません。URLに指定されたノードはシードとして扱われ、Javaクライアントはシステムテーブルやclickhouse-keeperもしくはzookeeperからさらに多くのノードを自動で検出します。

自動検出設定に関するオプションは以下の通りです:

プロパティデフォルト説明
auto_discoveryfalseクライアントがシステムテーブルまたはclickhouse-keeper/zookeeperからさらに多くのノードを検出するかどうか
node_discovery_interval0ノード検出の間隔をミリ秒で指定し、ゼロや負の値は一回限りの検出を意味します
node_discovery_limit100一度に検出できるノードの最大数。ゼロや負の値は制限なしを意味します

ロードバランシング

Javaクライアントはロードバランシングポリシーに従って、リクエストを送信するClickHouseノードを選択します。一般に、ロードバランシングポリシーは以下のことを担当します:

  1. 管理されているノードリストからノードを取得する
  2. ノードの状態を管理する
  3. (もし自動検出が有効であれば)ノード検出のためのバックグラウンドプロセスをオプションでスケジュールし、ヘルスチェックを実行する

ロードバランシングの設定に関するオプション一覧は以下の通りです:

プロパティデフォルト説明
load_balancing_policy""ロードバランシングポリシーとして利用できるのは:
  • firstAlive - 管理ノードリストから最初の正常なノードにリクエストが送られます
  • random - 管理ノードリストからランダムに選ばれたノードにリクエストが送られます
  • roundRobin - 管理ノードリストの各ノードに順番にリクエストが送られます
  • ClickHouseLoadBalancingPolicyを実装した完全修飾クラス名 - カスタムロードバランシングポリシー
  • 指定がなければ、管理ノードリストの最初のノードにリクエストが送られます
    load_balancing_tags""ノードをフィルタリングするためのロードバランシングタグ。指定されたタグを持つノードにのみリクエストが送られます
    health_check_interval0ヘルスチェックの間隔をミリ秒で指定し、ゼロや負の値は一回限りを意味します
    health_check_methodClickHouseHealthCheckMethod.SELECT_ONEヘルスチェックの方法。以下のうち一つ:
  • ClickHouseHealthCheckMethod.SELECT_ONE - select 1クエリでのチェック
  • ClickHouseHealthCheckMethod.PING - 一般により高速なプロトコル固有のチェック
  • node_check_interval0ノードチェックの間隔をミリ秒で指定し、負の数はゼロと見なされます。特定のノードの最後のチェックから指定された時間が経過している場合にノードの状態がチェックされます。
    health_check_intervalnode_check_intervalの違いは、health_check_intervalはノードのリスト(すべてもしくは誤っているものに対して)の状態をチェックするバックグラウンドジョブをスケジュールするオプションであるのに対し、node_check_intervalは特定のノードの最後のチェックから指定された時間が経過していることを指定するオプションです
    check_all_nodesfalseすべてのノードと誤動作しているノードのどちらに対してヘルスチェックを実行するかを指定します

    フェイルオーバーとリトライ

    Javaクライアントは、失敗したクエリに対するフェイルオーバーとリトライの動作をセットアップするための設定オプションを提供します:

    プロパティデフォルト説明
    failover0リクエストに対してフェイルオーバーが発生できる最大回数。ゼロまたは負の値はフェイルオーバーなしを意味します。フェイルオーバーは負の値を意味し、異なるノードに失敗したリクエストを送信します。
    retry0リクエストに対してリトライが発生できる最大回数。ゼロまたは負の値はリトライなしを意味します。ClickHouseサーバがNETWORK_ERRORエラーコードを返した場合のみ、リトライが行われます。
    repeat_on_session_locktrueセッションがロックされてタイムアウトする場合(session_timeout または connect_timeout に従う)の実行を繰り返すかどうかを指定します。ClickHouseサーバがSESSION_IS_LOCKEDエラーコードを返した場合に、失敗したリクエストが繰り返されます。

    カスタムHTTPヘッダーの追加

    JavaクライアントはリクエストにカスタムHTTPヘッダーを追加するためのHTTP/Sトランスポートレイヤーをサポートしています。 custom_http_headersプロパティを使用し、ヘッダーを,で区切って指定します。ヘッダーキー/値は=で分割する必要があります。

    Javaクライアントサポート

    options.put("custom_http_headers", "X-ClickHouse-Quota=test, X-ClickHouse-Test=test");

    JDBCドライバー

    properties.setProperty("custom_http_headers", "X-ClickHouse-Quota=test, X-ClickHouse-Test=test");