Kafka から ClickHouse
ClickHouse Cloud をご利用の場合は、代わりに ClickPipes の利用をお勧めします。ClickPipes は、プライベートネットワーク接続に対応しており、インジェストとクラスターリソースを個別にスケーリングできるほか、Kafka データを ClickHouse にストリーミングで取り込むための包括的な監視機能を備えています。
概要
手順
1. 準備
2. ClickHouse を設定する
config.xml で設定する必要があります。ここでは、SASL で保護されたインスタンスに接続することを前提としています。これは、Confluent Cloud と連携する際に最も簡単な方法です。
conf.d/ ディレクトリ配下の新しいファイルに配置するか、既存の設定ファイルに統合してください。設定可能な項目については、こちらを参照してください。
このチュートリアルで使用するため、KafkaEngine という名前のデータベースも作成します:
3. 宛先テーブルを作成する
4. トピックを作成してデータを投入する
github という名前のトピックを 5 つのパーティションで作成できます。
5. Kafka テーブルエンジン を作成する
JSONEachRow を使用している点に注意してください。github と clickhouse という値は、それぞれ トピック 名とコンシューマグループ名を表します。トピックs には実際には複数の値を指定できます。
github_queue に対して単純な select を実行すると、いくつかの行を読み取れるはずです。これにより consumer の offset が進むため、リセットしない限り、これらの行は再度読み取れなくなる点に注意してください。limit と、必須パラメータである stream_like_engine_allow_direct_select. にも注意してください。
6. materialized view を作成する
7. 行が挿入されていることを確認する
主な操作
メッセージ消費の停止と再開
Kafka メタデータの追加
_ で始まります。
仮想カラムの完全な一覧はこちらで確認できます。
仮想カラムをテーブルに反映するには、materialized view を削除し、Kafka エンジンのテーブルを再アタッチしてから、materialized view を再作成する必要があります。
Kafka エンジン設定の変更
問題のデバッグ
clickhouse-server.err.log を使用することを推奨します。基盤となるKafkaクライアントライブラリ librdkafka については、設定によりさらに詳細なトレースログを有効にできます。
不正な形式のメッセージの処理
- メッセージのフィールドは文字列として扱います。必要に応じて、materialized view ステートメント内で関数を使ってクレンジングや CAST を行えます。これは本番向けの解決策ではありませんが、一度限りのインジェストには役立つ場合があります。
- トピックから JSON を読み込み、JSONEachRow フォーマットを使用している場合は、設定
input_format_skip_unknown_fieldsを使用してください。データの書き込み時、デフォルトでは、入力データにターゲットテーブルに存在しないカラムが含まれていると、ClickHouse は例外をスローします。ただし、このオプションを有効にすると、こうした余分なカラムは無視されます。これも本番レベルの解決策ではなく、他の利用者を混乱させる可能性があります。 - 設定
kafka_skip_broken_messagesの利用も検討してください。これを使うには、不正な形式のメッセージに対するブロックごとの許容度を、kafka_max_block_sizeを踏まえてユーザーが指定する必要があります。この許容度を超えた場合 (絶対メッセージ数で判定) 、通常どおり例外が発生し、それ以外のメッセージはスキップされます。
配信セマンティクスと重複に関する課題
クォーラムベースのインサート
ClickHouse から Kafka へ
手順
1. 行を直接挿入する
2. materialized view を使う
github_out または同等のものを作成してください。Kafka テーブルエンジン github_out_queue がこのトピックを指していることを確認してください。
github_out_mv を作成し、GitHub テーブルを参照するように設定します。これがトリガーされると、上記のエンジンに行が insert されます。これにより、GitHub テーブルへの追加分は新しい Kafka トピック にプッシュされます。
github_out トピックを読み取れば、メッセージが配信されたことを確認できるはずです。
クラスターとパフォーマンス
ClickHouseクラスターの使用
パフォーマンスのチューニング
- パフォーマンスは、メッセージサイズ、フォーマット、ターゲットテーブルの types によって異なります。単一のテーブルエンジンで 10 万行/秒は十分に達成可能な水準です。デフォルトでは、メッセージは
kafka_max_block_sizeパラメーターで制御されるブロック単位で読み取られます。これはデフォルトで max_insert_block_size に設定されており、既定値は 1,048,576 です。メッセージが極端に大きい場合を除き、この値はほぼ常に増やすべきです。500k ~ 1M 程度の値も珍しくありません。スループットへの影響をテストして評価してください。 - テーブルエンジンのコンシューマー数は
kafka_num_consumersで増やせます。ただし、デフォルトではkafka_thread_per_consumerを既定値の1から変更しない限り、インサートは単一スレッドで直列化されます。フラッシュが並列に実行されるよう、これを1に設定してください。なお、N 個のコンシューマーを持つ Kafka engine テーブル (kafka_thread_per_consumer=1) を作成することは、それぞれに materialized view があり、kafka_thread_per_consumer=0が設定された N 個の Kafka engine を作成するのと論理的に等価です。 - コンシューマー数の増加は無償ではありません。各コンシューマーは独自のバッファーとスレッドを保持するため、サーバーのオーバーヘッドが増えます。まずは可能であればクラスター全体で線形にスケールさせ、コンシューマーによるオーバーヘッドを意識してください。
- Kafka メッセージのスループットにばらつきがあり、遅延を許容できる場合は、より大きなブロックがフラッシュされるよう
stream_flush_interval_msを増やすことを検討してください。 - background_message_broker_schedule_pool_size は、バックグラウンドタスクを実行するスレッド数を設定します。これらのスレッドは Kafka ストリーミングに使用されます。この設定は ClickHouseサーバーの起動時に適用され、ユーザーセッション中に変更することはできません。既定値は 16 です。ログにタイムアウトが見られる場合は、この値を増やすのが適切なことがあります。
- Kafka との通信には
librdkafkaライブラリが使用されており、このライブラリ自体もスレッドを作成します。そのため、多数の Kafka テーブルやコンシューマーがあると、大量のコンテキストスイッチが発生する可能性があります。この負荷はクラスター全体に分散し、可能であればターゲットテーブルのみをレプリケートするか、1 つのテーブルエンジンで複数のトピックを読み取ることを検討してください。値のリストがサポートされています。1 つのテーブルから複数の materialized view を読み取ることができ、それぞれが特定のトピックのデータをフィルタリングできます。
追加の設定
- Kafka_max_wait_ms - 再試行する前に Kafka からメッセージを読み取る際の待機時間 (ミリ秒) です。ユーザープロファイルレベルで設定し、デフォルト値は 5000 です。