クラスターの負荷の不均衡は、一部のノードが他のノードよりも著しく多くのトラフィックを処理し、クエリの低速化、インデックス作成の遅延、またはノードの障害を引き起こす場合に発生します。このトピックでは、Alibaba Cloud Elasticsearch クラスターにおける負荷不均衡の主な原因と、それぞれの解決方法について説明します。
症状
負荷の不均衡は、通常、次の 2 つの形で現れます。
-
ディスク使用率はノード間でほぼ均等ですが、特定のノードで CPU 使用率または load_1m が急上昇します。
-
ディスク使用率がノード間で大幅に異なり、CPU 使用率または load_1m がその不均衡を裏付けます。
原因
可能性の高い順に示します。
-
不適切なシャード割り当て:最も一般的な原因です。最初にこれを確認してください。
-
不均一なセグメントサイズ:単一のシャードに大きなセグメントが存在すると、そのシャードでのクエリが低速になります。
ホットデータとコールドデータの未分離 — クエリが特定のノードにルーティングされ、負荷が集中します。
-
不均一な永続的接続:まれなケースです。Server Load Balancer (SLB) を使用するマルチゾーンデプロイメントに影響します。
これらの原因のいずれも当てはまらない場合は、Alibaba Cloud のテクニカルサポートにお問い合わせください。
不適切なシャード割り当て
シナリオ
クラスターには 3 つの専用マスターノードと 9 つのデータノードがあります。マスターノード:16 vCPU、32 GiB メモリ。データノード:32 vCPU、64 GiB メモリ。ピーク時 (16:21–18:00) に、クラスターは約 2,000 の読み取り QPS と 1,000 の書き込み QPS を処理します。2 つのノードで CPU 使用率が 100% に達し、クエリのパフォーマンスが低下します。
分析
-
Elastic Compute Service (ECS) インスタンスとネットワークモニタリングの確認。ピーク時には、クエリの QPS が急上昇し、影響を受けるノードの CPU 使用率が急激に上昇します。これにより、高負荷のノードがほとんどのクエリトラフィックを処理していることが確認されます。
-
GET _cat/shards?vを実行してシャードの分散を確認します。出力から、testインデックスのシャードが高負荷のノードに集中していることがわかります。これらのノードのディスク使用率も高くなっています。不均一なシャード割り当てはストレージの不均衡を引き起こし、より多くのデータを持つノードがより多くの読み取りおよび書き込みトラフィックを処理することになります。 -
GET _cat/indices?vを実行して、インデックス設定を確認します。testインデックスには 5 つのプライマリシャードと、プライマリあたり 1 つのレプリカがあります。 シャードは均等に分散されておらず、一部のドキュメントには.delのマークが付いています。 Elasticsearch が検索する際、.delとマークされたドキュメントをスキャンして除外します。これは検索効率を低下させる余分な作業です。 これらのドキュメントを削除するには、オフピーク時に 強制マージ を実行します。pri rep docs.count docs.deleted store.size pri.store.size 1 1 8640 0 6.7mb 3.3mb 1 1 8639 0 6.7mb 3.3mb 1 1 8639 0 6.7mb 3.3mb 1 1 297847 488 688.7mb 344.8mb 1 1 93230 364 222.1mb 111mb 1 1 297803 588 693.5mb 346.1mb 1 1 297756 540 697.5mb 348.5mb 1 1 297852 536 687.9mb 343.4mb 1 1 297750 588 693.1mb 344.2mb 1 1 8639 0 6.7mb 3.3mb 1 1 8639 0 6.7mb 3.3mb 1 1 2 0 19.3kb 8.3kb 3 1 0 0 1.1kb 576b 3 1 71888299 15614684 124gb 64.6gb 3 1 0 0 1.1kb 576b 1 1 2661 0 2.2mb 1.1mb 1 1 8639 0 6.7mb 3.3mb 1 1 8639 0 6.6mb 3.3mb 1 1 297732 540 700.5mb 349.9mb 1 1 297795 540 691.6mb 344.7mb -
クラスターログと低速ログの確認。すべてのクエリは通常の Term クエリであり、クラスターログにエラーはありません。根本原因はクエリレベルの問題ではなく、シャードの分散にあります。
根本原因
不均一なシャード割り当てにより、ストレージとトラフィックが一部のノードに集中し、CPU の不均衡が発生します。
シャードを再調整すると、CPU 使用率はノード間で均等になります。

ソリューション
インデックスを作成する前に、シャード数を計画します。下記の「シャード計画のガイドライン」をご参照ください。
シャード計画のガイドライン
シャードの数とサイズは、クラスターの安定性とパフォーマンスを左右します。各インデックスのシャードを計画する際は、これらのガイドラインを使用してください。
7.x より前のバージョンの Elasticsearch では、デフォルトは 5 つのプライマリシャードとプライマリごとに 1 つのレプリカです。7.x 以降では、デフォルトは 1 つのプライマリシャードと 1 つのレプリカです。
|
制約 |
ガイドライン |
|
シャードサイズ (低スペックノード) |
シャードあたり最大 30 GB |
|
シャードサイズ (高スペックノード) |
シャードあたり最大 50 GB |
|
シャードサイズ (ログ分析または非常に大きなインデックス) |
シャードあたり最大 100 GB |
|
クラスターあたりの合計シャード数 |
プライマリシャードとレプリカシャードの合計数が、データノード数と等しいか、その倍数になるようにします |
|
ノードあたりのシャード数 |
メモリサイズ (GiB) × 30:これを超えるとファイルハンドルの枯渇リスクがあります |
|
ノードあたりのインデックスごとのシャード数 |
最大 5 シャード |
設定するプライマリシャードの数が多いほど、クラスターのパフォーマンスオーバーヘッドは高くなります。
自動インデックス作成機能を有効にしている場合は、シナリオベースの設定テンプレートを使用してシャード設定を調整し、シャードが均等に分散されるようにします。
不均一なセグメントサイズ
シナリオ
クラスター内の 1 つのノードで CPU 使用率が急上昇し、クエリパフォーマンスに影響を与えています。test インデックスには 3 つのプライマリシャードと、プライマリごとに 1 つのレプリカがあり、ノード間で均等に分散されています。このインデックスには、delete.doc とマークされたドキュメントが多数含まれています。ECS インスタンスは正常であることが確認されています。

分析
-
クエリ本文に "profile": true を追加します。プロファイリングの出力から、
testインデックスのシャード 1 が他のシャードよりもクエリに時間がかかっていることがわかります。 -
preference=_primaryとpreference=_replicaを使用してクエリを実行し、両方とも"profile": trueを指定します。シャード 1 のプライマリシャードがそのレプリカよりも低速であることから、シャード 1 が原因であると特定できます。 -
次のコマンドを実行して、シャード 1 のセグメントを検査します。
プライマリシャードとそのレプリカの間でドキュメント数に差異が生じるのには、2 つの理由が考えられます。- 同期のレイテンシー: ドキュメントが継続的に書き込まれている場合、レプリカが一時的に遅れることがあります。書き込みが停止すると、カウントは収束します。- 自動生成されたドキュメント ID を使用した同時削除: 自動生成された ID を使用してドキュメントを書き込み、書き込まれたばかりのドキュメントに対して Delete by Query リクエストを送信すると、書き込みがレプリカに伝播する前に、プライマリシャードで削除が実行されます。その結果、レプリカは削除なしで書き込みを受信するため、レプリカ上のドキュメント数が多くなります。さらに、プライマリには
doc.deleteとマークされたドキュメントが蓄積されます。GET _cat/segments/index?v&h=shard,segment,size,size.memory,ip GET _cat/shards?v出力から、シャード 1 がそのレプリカシャードよりもセグメントが大きく、ドキュメント数が多いことがわかります。このセグメントサイズの差が負荷の不均衡を引き起こしています。
ソリューション (いずれかを選択)
-
オフピーク時間帯に、force merge を呼び出して小さなセグメントを統合し、
delete.docドキュメントを削除します。 -
プライマリシャードをホストしているノードを再起動します。これにより、レプリカがプライマリに昇格し、そこから新しいレプリカが生成されるため、両方のシャードのセグメント構造が同一になります。
最適化後、負荷はノード間で均等になります。

不均一な永続的接続
この原因はまれであり、マルチゾーンデプロイメントに特有のものです。
シナリオ
クラスターはゾーン B とゾーン C の 2 つのゾーンにまたがってデプロイされています。ゾーン C のノードは、ゾーン B のノードよりも一貫して高い負荷を担っています。この不均衡は、ハードウェアの違いや不均一なデータ分散によるものではありません。

分析
-
過去 4 日間の CPU 使用率を表示します。モニタリングデータから、特定の時点で CPU 使用率が大幅に変化したことがわかります。

-
各ノードの TCP 接続を確認します。TCP 接続の数がゾーン B とゾーン C で大幅に異なり、ネットワーク接続の分散に問題があることを示しています。

-
クライアントの接続動作を確認します。クライアントは永続的接続を使用し、新しい接続をほとんど作成しません。マルチゾーンアーキテクチャでは、各スケジューリングユニットが接続を確立する際に、独立して最適なノードを選択します。新しい接続の数が少ない場合、複数のスケジューリングユニットが同じノードを選択する可能性があります。さらに、Elasticsearch のクライアントノードは、同じゾーン内のノードにリクエストを転送することを優先するため、トラフィックが 1 つのゾーンに集中します。
ソリューション (いずれかを選択)
-
クライアントで接続の有効期間 (time-to-live) を設定します。の
httpClientBuilder.setConnectionTimeToLive()を使用して、定期的な接続の更新を強制します。たとえば、5 分間の TTL を設定するには、次のようにします。この目的には
setConnectionTimeToLive()を使用します。setKeepAliveStrategy()は、接続の再分散において効果が劣ります。httpClientBuilder.setConnectionTimeToLive(5, TimeUnit.MINUTES)詳細については、「HttpAsyncClientBuilder」をご参照ください。
-
クライアントを同時に再起動して、すべてのノードにわたって新しい接続を同時に強制的に作成します。
-
専用のクライアントノードを使用してトラフィックをルーティングします。クライアントノードはリクエストをデータノードに転送し、ルーティングレイヤーをストレージレイヤーから分離します。クライアントノードの負荷が高くなっても、データノードは影響を受けません。
最適化後、負荷はゾーン間で均等に分散されます。

単一インデックスにおける不均一なシャード
シナリオ
シャードはノード間で均等に分散されているように見えますが、特定のインデックスでは、高負荷のノードに、より多くのシャード、またはより大きなシャードが存在します。
ソリューション
index.routing.allocation.total_shards_per_node を設定して、1 つのノードに配置できる単一インデックスのシャード数の上限を定めます。
値は、(プライマリシャード + レプリカシャード) / データノード数 のように計算します。結果が整数でない場合は、切り上げます。
PUT index_name/_settings
{
"index.routing.allocation.total_shards_per_node": "3"
}