はじめに
このガイドでは、まず ClickHouse が分散テーブルを介してクエリを 複数の分片にどのように分散するのかを説明し、その後、クエリの実行で 複数のレプリカをどのように活用できるのかを説明します。shared-nothing アーキテクチャでは、クラスターは通常、複数の分片に 分割され、各分片には全体データの一部が格納されます。これらの分片の 上位には分散テーブルがあり、データ全体を単一のビューとして提供します。 読み取りはローカルテーブルに送ることができます。その場合、クエリの実行は 指定した分片でのみ行われます。あるいは分散テーブルに送ることもでき、その 場合は各分片で指定されたクエリが実行されます。分散テーブルに対するクエリを 受けたサーバーがデータを集約し、クライアントに応答を返します。 上の図は、クライアントが分散テーブルにクエリを実行した際に何が起こるかを示しています。
- SELECT クエリは、任意のノード上の分散テーブルに送信されます (ラウンドロビン戦略を介するか、ロードバランサーによって特定のサーバーに ルーティングされた後) 。このノードがコーディネーターとして動作します。
- このノードは、分散テーブルで指定された情報に基づいて、 クエリを実行する必要がある各分片を特定し、クエリを 各分片に送信します。
- 各分片はローカルでデータを読み取り、フィルタリングと集約を行った後、 マージ可能な状態をコーディネーターに返します。
- コーディネーターとなるノードがデータをマージし、その後 応答をクライアントに返します。
非分片アーキテクチャ
並列レプリカの紹介
- クライアントからのクエリは、ロード バランサーを経由して 1 つのノードに送られます。このノードがこのクエリのコーディネーターになります。
- そのノードは各パーツの索引を解析し、処理対象のパーツと グラニュールを選択します。
- コーディネーターは、ワークロードを 異なるレプリカに割り当て可能な一連のグラニュールに分割します。
- 各グラニュールの集合は対応するレプリカで処理され、完了すると マージ可能な状態がコーディネーターに送られます。
- 最後に、コーディネーターがレプリカからのすべての結果をマージし、 クライアントにレスポンスを返します。
- 利用できないレプリカがある場合があります。
- ClickHouse のレプリケーションは非同期であるため、ある時点では一部のレプリカが 同じパーツを持っていない可能性があります。
- レプリカ間のテールレイテンシを何らかの方法で扱う必要があります。
- ファイルシステムキャッシュは各レプリカ上の アクティビティに応じて異なるため、タスクをランダムに割り当てると、 キャッシュ局所性の観点では最適でないパフォーマンスにつながる可能性があります。
アナウンス
- クライアントからのクエリは、ロード バランサーを経由して 1 つのノードに送られます。このノードが、このクエリのコーディネーターになります。
- コーディネーターとなるノードは、 クラスター内のすべてのレプリカからアナウンスを取得するためのリクエストを送信します。レプリカごとに、テーブルの現在のパーツ集合の見え方が わずかに異なる場合があります。そのため、 不正確なスケジューリング判断を避けるには、この情報を収集する必要があります。
- その後、コーディネーターとなるノードはアナウンスを使って、 各レプリカに割り当て可能な グラニュール の集合を定義します。たとえばここでは、 パーツ 3 の グラニュール はレプリカ 2 には 1 つも割り当てられていないことがわかります。 これは、このレプリカがアナウンスでこのパーツを通知しなかったためです。 また、 レプリカ 3 はアナウンスを返さなかったため、タスクが 1 つも割り当てられていない点にも注意してください。
- 各レプリカが自分に割り当てられた グラニュール のサブセットに対してクエリを処理し、 マージ可能な状態がコーディネーターに送り返されると、 コーディネーターが結果をマージし、そのレスポンスがクライアントに送信されます。
動的協調
- レプリカは、タスクを処理できることをコーディネーターノードに知らせます。 また、どれだけの作業を処理できるかを指定することもできます。
- コーディネーターはレプリカにタスクを割り当てます。
- レプリカ1と2は、自分たちのタスクを非常にすばやく完了します。 そのため、コーディネーターノードに別のタスクを要求します。
- コーディネーターはレプリカ1と2に新しいタスクを割り当てます。
- すべてのレプリカが、それぞれのタスクの処理を完了しました。 さらにタスクを要求します。
- コーディネーターは、アナウンスを使って未処理のタスクが残っているかどうかを 確認しますが、残っているタスクはありません。
- コーディネーターは、すべての処理が完了したことをレプリカに伝えます。 その後、マージ可能なすべての状態をマージして、クエリに応答します。
cache の局所性の管理
| レプリカ 1 | レプリカ 2 | レプリカ 3 | |
|---|---|---|---|
| パート 1 | g1, g6, g7 | g2, g4, g5 | g3 |
| パート 2 | g1 | g2, g4, g5 | g3 |
| パート 3 | g1, g6 | g2, g4, g5 | g3 |
max_parallel_replicas がレプリカ数より少ない場合は、クエリ実行のためにランダムにレプリカが選択されます。
タスクのスティーリング
制限事項
以下に挙げた制限事項以外の問題が見つかり、その原因が並列レプリカにあると思われる場合は、
GitHub でラベル
comp-parallel-replicas を付けて issue を作成してください。| Limitation | Description |
|---|---|
| 複雑なクエリ | 現時点では、並列レプリカはシンプルなクエリでは比較的うまく機能します。CTE、サブクエリ、JOIN、ネストしたクエリなど、クエリの複雑さが増すと、クエリパフォーマンスに悪影響を及ぼす可能性があります。 |
| 小規模なクエリ | 処理する行数がそれほど多くないクエリでは、複数のレプリカで実行しても性能が向上しないことがあります。これは、レプリカ間の協調に伴うネットワーク時間によって、クエリ実行に余分なサイクルが発生するためです。この問題は、設定 parallel_replicas_min_number_of_rows_per_replica を使用することで抑えられます。 |
| FINAL では並列レプリカは無効 | |
| プロジェクションは並列レプリカと併用されません | |
| 高カーディナリティのデータと複雑な集約 | 大量のデータ送信が必要な高カーディナリティの集約では、クエリが大幅に遅くなる可能性があります。 |
| 新しいアナライザとの互換性 | 新しいアナライザにより、特定のシナリオではクエリ実行が大幅に遅くなったり、逆に速くなったりする可能性があります。 |
| Setting | Description |
|---|---|
enable_parallel_replicas | 0: 無効1: 有効 2: 並列レプリカの使用を強制します。使用されない場合は例外をスローします。 |
cluster_for_parallel_replicas | 並列レプリカに使用するクラスター名です。ClickHouse Cloud を使用している場合は default を使用してください。 |
max_parallel_replicas | 複数のレプリカでクエリを実行する際に使用するレプリカの最大数です。クラスター内のレプリカ数より少ない値を指定すると、ノードはランダムに選択されます。この値は、水平スケーリングを考慮してオーバーコミットすることもできます。 |
parallel_replicas_min_number_of_rows_per_replica | 処理対象の行数に基づいて、使用するレプリカ数を制限するのに役立ちます。使用されるレプリカ数は次の式で決まります。estimated rows to read / min_number_of_rows_per_replica。 |
enable_analyzer | 並列レプリカによるクエリ実行は、アナライザが有効な場合にのみサポートされます |
並列レプリカの問題の調査
system.query_log テーブルで確認できます。また、
system.events
テーブルを見ると、サーバー上で発生したすべてのイベントを確認できます。さらに、
clusterAllReplicas テーブル関数を使うと、すべてのレプリカ上のテーブルを確認できます
(Cloud ユーザーの場合は default を使用してください) 。
Query
レスポンス
レスポンス
Response
system.text_log テーブルには、並列レプリカを使用したクエリの実行に関する情報も
含まれています。
Query
レスポンス
レスポンス
Response
EXPLAIN PIPELINE を使用することもできます。これにより、ClickHouse
がクエリをどのように実行し、クエリの実行に
どのようなリソースが使われるかを確認できます。例として、次のクエリを見てみましょう。
EXPLAIN PIPELINE (without parallel replica)
EXPLAIN PIPELINE (with parallel replica)