サポートが必要な場合は、リポジトリで issue を報告するか、ClickHouse の公開 Slack で質問してください。
ライセンス
環境要件
バージョン互換性マトリックス
主な機能
- すぐに使える exactly-once セマンティクスを備えています。これは、KeeperMap という ClickHouse の新しいコア機能 (コネクタの状態ストアとして使用) を基盤としており、シンプルなアーキテクチャを実現します。
- 3rd-party の状態ストアをサポート: 現在のデフォルトはインメモリですが、KeeperMap も利用できます (Redis は近日追加予定) 。
- コアインテグレーション: ClickHouse により開発・保守・サポートされています。
- ClickHouse Cloud に対して継続的にテストされています。
- スキーマを定義したデータ挿入とスキーマレスのデータ挿入に対応。
- ClickHouse のすべてのデータ型をサポートします。
インストール手順
接続情報を確認する
ClickHouse Cloud サービスの詳細は、ClickHouse Cloud コンソールで確認できます。
サービスを選択し、Connect をクリックします。
HTTPS を選択します。接続情報は
curl コマンドの例として表示されます。
セルフマネージド ClickHouse を使用している場合、接続情報は ClickHouse 管理者によって設定されます。
一般的なインストール手順
- ClickHouse Kafka Connect Sink リポジトリの Releases ページから、コネクタの JAR ファイルを含む ZIP アーカイブをダウンロードします。
- ZIP ファイルの内容を展開し、任意の場所にコピーします。
- Confluent Platform がプラグインを検出できるように、Connect のプロパティファイル内の plugin.path 設定に、プラグインディレクトリへのパスを追加します。
- 設定で topic 名、ClickHouse インスタンスの hostname、パスワードを指定します。
- Confluent Platform を再起動します。
- Confluent Platform を使用している場合は、Confluent Control Center UI にログインし、利用可能なコネクタの一覧に ClickHouse Sink が含まれていることを確認します。
設定オプション
- 接続情報: ホスト名 (必須) とポート (任意)
- ユーザー認証情報: パスワード (必須) とユーザー名 (任意)
- コネクタクラス:
com.clickhouse.kafka.connect.ClickHouseSinkConnector(必須) - topics または topics.regex: ポーリングする Kafka トピック。トピック名はテーブル名と一致している必要があります (必須)
- キーコンバータと値コンバータ: トピック上のデータの種類に応じて設定します。worker の設定ですでに定義されていない場合は必須です。
ターゲットテーブル
前処理
サポートされているデータ型
-
(1) - JSON がサポートされるのは、ClickHouse の設定で
input_format_binary_read_json_as_string=1が指定されている場合のみです。これは RowBinary フォーマットファミリーでのみ機能し、この設定は insert リクエスト内のすべてのカラムに影響するため、それらはすべて文字列である必要があります。この場合、コネクタは STRUCT を JSON 文字列に変換します。 -
(2) - struct に
oneofのような ユニオン がある場合、コンバータはフィールド名に プレフィックス/接尾辞 を追加しないよう設定する必要があります。generate.index.for.unions=falseのProtobufConverter用設定 があります。
設定レシピ
基本構成
localhost:8443 で SSL を有効にした ClickHouse サーバーが稼働しており、データがスキーマレスの JSON 形式であることを前提としています。
上記のコネクタ設定では、
connector.client.config.override.policy=All を使用して、ワーカー設定でクライアントのオーバーライドを有効にする必要があります。詳細については、Kafka Connect のドキュメントを参照してください。複数のトピックを使用する基本構成
DLQ を使用する基本設定
さまざまなデータフォーマットでの使用
Avro スキーマの対応
Avro 型マッピング
io.confluent.connect.avro.AvroConverter で定義されています。変換ロジックの詳細については、Kafka Connect のドキュメントを参照してください。
✅: サポート
❌: 非サポート
️⚠️: 一部サポート
Kafka Connect の型と ClickHouse の型の対応については、サポートされているデータ型を参照してください。
サポートされていない Avro スキーマ
fixedのdecimal論理型
- Nullable ユニオン
- レコード型のユニオン
Protobuf スキーマ対応
Protobuf 型マッピング
io.confluent.connect.protobuf.ProtobufConverter で定義されています。変換ロジックの詳細については、Kafka Connect のドキュメントを参照してください。
✅: サポートあり
❌: サポートなし
️⚠️: 一部サポート
Kafka Connect の型と ClickHouse の型の対応については、サポートされているデータ型を参照してください。
oneof フィールドを ClickHouse のカラムに変換する際の注意
oneof) を ClickHouse の Variant 型に変換することをサポートしていません。代わりに、ClickHouse テーブルのスキーマでは、oneof フィールドを個別の Nullable フィールドとして列挙してください。
たとえば:
サポートされていない Protobuf スキーマ
- 複数メッセージのユニオン (CH バージョン 26.1 より前)
allow_experimental_nullable_tuple_type=1 を設定すると、このスキーマがサポートされます (こちらのドキュメントページを参照) 。
JSON スキーマのサポート
Stringのサポート
内部バッファリング
poll() 呼び出しで取得したレコードを蓄積し、より大きなバッチとして ClickHouse にフラッシュできます。これにより、各 poll でパーティションごとの小さなバッチが多数生成されるワークロードでは、スループットが向上する場合があります。
主な動作:
bufferCountは、フラッシュ前にバッファリングするレコード数を制御します。bufferFlushTimeは、バッファリングされたレコードをフラッシュするまでの最大待機時間 (ミリ秒) を設定します。bufferFlushTimeは、bufferCount > 0の場合にのみ有効です。bufferCount=0およびbufferFlushTime=0の場合、バッファリングは無効のままです (デフォルトの動作) 。exactlyOnce=trueの場合、バッファリングはサポートされません。
exactlyOnce=false を指定して exactly-once モードを無効にするか、bufferCount=0 を指定してバッファリングを無効にしてください。
例:
ロギング
監視
ClickHouse固有のメトリクス
Kafka Producer/Consumer メトリクス
records-sent-total: トピックに送信されたレコードの総数bytes-sent-total: トピックに送信された総バイト数record-send-rate: 1 秒あたりに送信されたレコードの平均レートbyte-rate: 1 秒あたりに送信された平均バイト数compression-rate: 達成された圧縮率
records-sent-total: パーティションに送信されたレコードの総数bytes-sent-total: パーティションに送信された総バイト数records-lag: パーティションの現在のラグrecords-lead: パーティションの現在のリードreplica-fetch-lag: レプリカのラグ情報
connection-creation-total: Kafka ノードに対して作成された接続の総数connection-close-total: クローズされた接続の総数request-total: ノードに送信されたリクエストの総数response-total: ノードから受信したレスポンスの総数request-rate: 1 秒あたりの平均リクエストレートresponse-rate: 1 秒あたりの平均レスポンスレート
- スループット: データのインジェスト率を追跡
- ラグ: ボトルネックや処理遅延を特定
- 圧縮: データ圧縮の効率を測定
- 接続の健全性: ネットワーク接続の状態と安定性を監視
Kafka Connect Framework のメトリクス
task-count: コネクタ内のタスク総数running-task-count: 現在実行中のタスク数paused-task-count: 現在一時停止中のタスク数failed-task-count: 失敗したタスク数destroyed-task-count: 破棄されたタスク数unassigned-task-count: 未割り当てのタスク数
running、paused、failed、destroyed、unassigned があります
エラーメトリクス:
deadletterqueue-produce-failures: 失敗した DLQ への書き込み数deadletterqueue-produce-requests: DLQ への書き込み試行総数last-error-timestamp: 直近のエラーのタイムスタンプrecords-skip-total: エラーによりスキップされたレコード総数records-retry-total: 再試行されたレコード総数errors-total: 発生したエラーの総数
offset-commit-failures: オフセットコミットの失敗数offset-commit-avg-time-ms: オフセットコミットの平均所要時間offset-commit-max-time-ms: オフセットコミットの最大所要時間put-batch-avg-time-ms: バッチ処理の平均所要時間put-batch-max-time-ms: バッチ処理の最大所要時間source-record-poll-total: ポーリングされたレコード総数
監視のベストプラクティス
- コンシューマラグを監視する: 処理のボトルネックを特定するため、パーティションごとの
records-lagを追跡します - エラー率を追跡する: データ品質の問題を検出するため、
errors-totalとrecords-skip-totalを監視します - タスクの健全性を確認する: タスクが正常に実行されていることを確認するため、タスクのステータスメトリクスを監視します
- スループットを測定する: インジェストのパフォーマンスを追跡するため、
records-send-rateとbyte-rateを使用します - 接続の健全性を監視する: ネットワークの問題を確認するため、ノードレベルの接続メトリクスを確認します
- 圧縮効率を追跡する: データ転送を最適化するため、
compression-rateを使用します
制限事項
- 削除には対応していません。
- バッチサイズは Kafka Consumer のプロパティを継承します。
- exactly-once のために KeeperMap を使用している場合、オフセットを変更または巻き戻したときは、その トピック に対応する KeeperMap の内容を削除する必要があります。 (詳細は下記のトラブルシューティングガイドを参照してください)
パフォーマンスチューニングとスループット最適化
パフォーマンスチューニングが必要になるのはどのような場合ですか?
- 高スループットのワークロード: Kafkaトピックから毎秒数百万件のイベントを処理する場合
- コンシューマラグ: データ生成の速度にコネクタが追いつかず、ラグが増大している場合
- リソース制約: CPU、メモリ、またはネットワークの使用を最適化する必要がある場合
- 複数のトピック: 大量のデータが流れる複数のトピックを同時に消費する場合
- 小さなメッセージサイズ: サーバー側のバッチ処理の恩恵を受けられる、小さなメッセージを大量に扱う場合
- 低〜中程度の量 (毎秒10,000メッセージ未満) を処理している
- コンシューマラグが安定しており、ユースケース上許容できる範囲に収まっている
- デフォルトのコネクタ設定ですでに必要なスループット要件を満たしている
- ClickHouseクラスターが流入する負荷を容易に処理できる
データフローを理解する
- Kafka Connect Framework がバックグラウンドで Kafka トピックからメッセージを取得します
- コネクタ がフレームワークの内部バッファからメッセージをポーリングします
- コネクタ はポーリングサイズに基づいてメッセージをバッチ化します
- ClickHouse は HTTP/S 経由でバッチ化された insert を受け取ります
- ClickHouse はその insert を処理します (同期または非同期)
Kafka Connect のバッチサイズ調整
fetch設定
fetch.min.bytes: フレームワークがデータをコネクタに渡す前に必要な最小データ量 (デフォルト: 1 byte)fetch.max.bytes: 1 回のリクエストでfetchできるデータ量の上限 (デフォルト: 52428800 / 50 MB)fetch.max.wait.ms:fetch.min.bytesに達しない場合に、データを返すまでの最大待機時間 (デフォルト: 500 ms)
Confluent Cloud では、これらの設定を変更するには Confluent Cloud でサポートケースを作成する必要があります。
ポーリング設定
max.poll.records: 1 回のポーリングで返されるレコードの最大数 (デフォルト: 500)max.partition.fetch.bytes: パーティションごとの最大データ量 (デフォルト: 1048576 / 1 MB)
Confluent Cloud では、これらの設定を変更するには、Confluent Cloud のサポートケースを作成する必要があります。
高スループット向けの推奨設定
上記のプロパティを使用するには、
connector.client.config.override.policy=All を指定して、ワーカー設定でクライアントのオーバーライドを有効にする必要があります。詳細は、Kafka Connect ドキュメントを参照してください。- バッチが大きいほど = ClickHouse へのインジェスト性能が向上し、パーツ数が減り、オーバーヘッドが低減
- バッチが大きいほど = メモリ使用量が増え、エンドツーエンドのレイテンシが高くなる可能性
- バッチが大きすぎる場合 = タイムアウト、OutOfMemory エラー、または
max.poll.interval.ms超過のリスク
非同期挿入
非同期 INSERT を使用するタイミング
- 小さなバッチが多数ある: コネクタが小さなバッチ (1 バッチあたり 1000 行未満) を高頻度で送信している
- 高い並行性: 複数のコネクタ タスクが同じテーブルに書き込んでいる
- 分散デプロイ: 異なるホスト上で多数のコネクタ インスタンスを実行している
- パーツ作成のオーバーヘッド: 「パーツが多すぎる」エラーが発生している
- 混在ワークロード: リアルタイム インジェストとクエリ ワークロードを組み合わせている
- すでに大きなバッチ (1 バッチあたり 10,000 行超) を、頻度を制御しながら送信している
- データを即座に可視化する必要がある (クエリですぐにデータを参照できる必要がある)
wait_for_async_insert=0を使用する exactly-once セマンティクス が要件と競合する- 代わりにクライアント側のバッチ処理の改善で効果を得られるユースケースである
非同期 INSERT の仕組み
- コネクタから INSERT クエリを受け取ります
- データをメモリ上のバッファに書き込みます (すぐにディスクへは書き込みません)
- コネクタに成功を返します (
wait_for_async_insert=0の場合) - 次のいずれかの条件が満たされると、バッファをディスクにフラッシュします。
- バッファが
async_insert_max_data_sizeに達する (デフォルト: 100 MB) - 最初の INSERT から
async_insert_busy_timeout_msミリ秒が経過する (デフォルト: 1000 ms) - 累積されたクエリ数が上限に達する (
async_insert_max_query_number、デフォルト: 100)
- バッファが
非同期 INSERT を有効にする
clickhouseSettings 設定パラメータに、非同期 INSERT の設定を追加します。
async_insert=1: 非同期挿入を有効にしますwait_for_async_insert=1(推奨) : コネクタは、データが ClickHouse ストレージにフラッシュされるまで待機してから確認応答します。これにより、配信が保証されます。wait_for_async_insert=0: コネクタは、バッファリング直後にただちに確認応答します。パフォーマンスは向上しますが、フラッシュ前にサーバーがクラッシュするとデータが失われる可能性があります。
非同期 INSERT の動作の調整
async_insert_max_data_size(デフォルト: 104857600 / 100 MB): フラッシュ前の最大バッファサイズasync_insert_busy_timeout_ms(デフォルト: 1000): フラッシュまでの最大時間 (ms)async_insert_stale_timeout_ms(デフォルト: 0): 最後の insert からフラッシュまでの時間 (ms)async_insert_max_query_number(デフォルト: 100): フラッシュ前の最大クエリ数
- 利点: パーツ数の削減、マージ性能の向上、CPU オーバーヘッドの低減、高い同時実行数下でのスループット向上
- 考慮事項: データをすぐにはクエリできないこと、エンドツーエンドのレイテンシがわずかに増加すること
- リスク:
wait_for_async_insert=0の場合、サーバークラッシュ時にデータが失われる可能性があること、大きなバッファによってメモリが逼迫する可能性があること
exactly-once セマンティクスの非同期 INSERT
exactlyOnce=true を使用する場合:
wait_for_async_insert=1 を使用してください。
非同期 INSERT の詳細については、ClickHouse async inserts documentation を参照してください。
コネクタの並列度
コネクタあたりのタスク数
- 実質的に有効なタスク数の上限 = トピックパーティション数
- 各タスクは ClickHouse への接続をそれぞれ維持します
- タスク数が増えるほどオーバーヘッドが大きくなり、リソース競合が発生する可能性があります
tasks.max をトピックパーティション数と同じ値に設定し、その後 CPU 使用率とスループットのメトリクスを見ながら調整してください。
バッチ処理時にパーティションを区別しない
exactlyOnce=false の場合にのみ使用してください。この設定では、より大きなバッチを作成してスループットを向上できますが、パーティションごとの順序保証は失われます。
複数の高スループットなトピック
topic2TableMap を使ってトピックをテーブルにマッピングしていて、挿入時のボトルネックによってコンシューマラグが発生している場合は、代わりにトピックごとにコネクタを 1 つずつ作成することを検討してください。
これが発生する主な理由は、現時点ではバッチが各テーブルに直列で挿入されるためです。
推奨事項: 高ボリュームのトピックが複数ある場合は、並列挿入スループットを最大化するために、トピックごとにコネクタインスタンスを 1 つずつデプロイしてください。
ClickHouse テーブルエンジンに関する考慮事項
MergeTree: ほとんどのユースケースに最適で、クエリと insert のパフォーマンスのバランスに優れていますReplicatedMergeTree: 高可用性に必要ですが、レプリケーションのオーバーヘッドが増えます- 適切な
ORDER BYを設定した*MergeTree: クエリパターンに合わせて最適化できます
接続プーリングとタイムアウト
socket_timeout(デフォルト: 30000 ms) : 読み取り操作の最大待機時間connection_timeout(デフォルト: 10000 ms) : 接続確立までの最大待機時間
パフォーマンスの監視とトラブルシューティング
- コンシューマラグ: Kafka の監視ツールを使用して、パーティションごとのラグを追跡します
- コネクタのメトリクス: JMX 経由で
receivedRecords、recordProcessingTime、taskProcessingTimeを監視します (監視を参照) - ClickHouse のメトリクス:
system.asynchronous_inserts: 非同期 INSERT バッファの使用状況を監視しますsystem.parts: マージの問題を検出するためにパーツ数を監視しますsystem.merges: 実行中のマージを監視しますsystem.events:InsertedRows、InsertedBytes、FailedInsertQueryを追跡します
ベストプラクティスの要約
- まずはデフォルト設定で始め、実際のパフォーマンスを測定してから調整する
- より大きなバッチを優先する: 可能であれば、1 回の insert あたり 10,000~100,000 行を目安にする
- 非同期 INSERT を使用する: 小さなバッチを多数送信する場合や、高い同時実行性が求められる場合に使用する
- exactly-once セマンティクスでは常に
wait_for_async_insert=1を使用する - 水平スケールする:
tasks.maxをパーティション数まで増やす - スループットの高い トピック ごとに 1 つのコネクタを使用する: スループットを最大化するため
- 継続的に監視する: コンシューマラグ、パーツ数、merge アクティビティを追跡する
- 十分にテストする: 本番環境にデプロイする前に、現実的な負荷をかけて設定変更を必ずテストする
例: 高スループット構成
上記のコネクタ設定では、worker の設定で
connector.client.config.override.policy=All を指定し、クライアント設定のオーバーライドを有効にする必要があります。詳しくは、Kafka Connect のドキュメントを参照してください。- 1 回の poll で最大 10,000 件のレコードを処理します
- より大きな INSERT を行うため、複数のパーティションにまたがってバッチ化します
- 16 MB のバッファで非同期 INSERT を使用します
- 8 個の task を並列実行します (パーティション数に合わせてください)
- 厳密な順序性よりもスループットを重視して最適化されています
トラブルシューティング
”トピック [someTopic] パーティション [0] の状態不一致”
この調整は exactly-once に影響する可能性があります。
“コネクタはどのようなエラーで再試行しますか?”
ClickHouseException- これは ClickHouse によってスローされる汎用的な例外です。 通常はサーバーが過負荷のときにスローされ、特に一時的なものと見なされるエラーコードは次のとおりです。- 3 - UNEXPECTED_END_OF_FILE
- 107 - FILE_DOESNT_EXIST
- 159 - TIMEOUT_EXCEEDED
- 164 - READONLY
- 202 - TOO_MANY_SIMULTANEOUS_QUERIES
- 203 - NO_FREE_CONNECTION
- 209 - SOCKET_TIMEOUT
- 210 - NETWORK_ERROR
- 241 - MEMORY_LIMIT_EXCEEDED
- 242 - TABLE_IS_READ_ONLY
- 252 - TOO_MANY_PARTS
- 285 - TOO_FEW_LIVE_REPLICAS
- 319 - UNKNOWN_STATUS_OF_INSERT
- 425 - SYSTEM_ERROR
- 999 - KEEPER_EXCEPTION
SocketTimeoutException- これはソケットがタイムアウトしたときにスローされます。UnknownHostException- これはホスト名を解決できないときにスローされます。IOException- これはネットワークに問題があるときにスローされます。
“すべてのデータが空白/ゼロになっている”
_ を使用) 。その結果、テーブル内のフィールドは “field1_field2_field3” という形式 (つまり “before_id”、“after_id” など) に従います。
“ClickHouse で Kafka のキーを使いたい”
value フィールドに保存されませんが、KeyToValue 変換を使うと、キーを value フィールド内の新しい _key フィールドに移動できます。