Elasticsearch シャード割り当ての問題: 原因と解決策

割り当て説明、ディスクチェック、ノードフィルター、安全なリカバリ手順を使用してElasticsearchのシャード割り当て問題を診断します。

Elasticsearchシャード割り当ての問題:原因と解決策

Elasticsearchのシャード割り当て問題は、通常、クラスターヘルスが黄色または赤色として表示されます。黄色はプライマリシャードが割り当てられているが、少なくとも1つのレプリカが割り当てられていないことを意味します。赤色は少なくとも1つのプライマリシャードが未割り当てであり、データの一部が利用できなくなる可能性があるため、回復する必要があることを意味します。

このガイドでは、割り当てブロッカーを見つけ、Allocation Explain APIの出力を読み取り、リスクが最も少ない修正方法を選択する方法を示します。目標は、データ損失を悪化させることなく割り当てを復元することです。

シャードの状態とクラスターヘルスについて

シャードは、Elasticsearchがデータノード全体に配置する単位です。シャードにはいくつかの状態があります:

  • STARTED: シャードはアクティブでリクエストを処理しています。
  • RELOCATING: シャードが1つのノードから別のノードに移動しています。
  • INITIALIZING: シャードが作成中または回復中です。
  • UNASSIGNED: シャードはクラスターメタデータに存在しますが、ノードに割り当てられていません。

クラスターヘルスはこれらのシャード状態に従います:

  • Green: すべてのプライマリシャードとレプリカシャードが割り当てられています。
  • Yellow: すべてのプライマリシャードが割り当てられていますが、1つ以上のレプリカが未割り当てです。
  • Red: 1つ以上のプライマリシャードが未割り当てです。検索は影響を受けるインデックスに対して部分的な結果を返すか失敗する可能性があり、それらのインデックスへの書き込みは失敗する可能性があります。

シャード割り当て失敗の一般的な原因

Elasticsearchはシャードを配置する前に割り当て判定子を使用します。単一のNO判定でシャードが未割り当てのままになる可能性があります。

ディスクのウォーターマーク

ディスクの圧迫は最も一般的な原因の1つです。Elasticsearchはディスクのウォーターマークを使用して、ノードがいっぱいになるのを防ぎます。ノードが低ウォーターマークまたは高ウォーターマークを超えると、割り当て判定がより制限的になります。フラッドステージのウォーターマークでは、Elasticsearchは影響を受けるインデックスに読み取り専用ブロックを追加して、ノードのディスク不足を防ぐことができます。

設定 一般的なデフォルト 効果
cluster.routing.allocation.disk.watermark.low 85% このしきい値を超えるノードへの追加シャードの割り当てを回避します。
cluster.routing.allocation.disk.watermark.high 90% シャードをノードから移動させ、ノードへのシャード配置を回避しようとします。
cluster.routing.allocation.disk.watermark.flood_stage 95% 影響を受けるインデックスへの書き込みをブロックする可能性があります。

何かを変更する前に、クラスターの実際の設定を確認してください:

GET /_cluster/settings?include_defaults=true&filter_path=**.disk.watermark*

次に、ノードのディスク使用量を確認します:

GET /_cat/allocation?v&h=node,disk.used_percent,disk.avail,disk.total,shards

空き容量を増やす、ディスクを追加する、データノードを追加する、古いインデックスを削除する、またはレプリカの負荷を減らします。フラッドステージブロックが設定された場合、ディスクの圧迫が修正された後にのみ削除します:

PUT /my_index/_settings
{
  "index.blocks.read_only_allow_delete": null
}

ノードの役割と割り当てフィルター

インデックスシャードは、データの役割と一致する割り当てフィルターを持つノードにのみ割り当てられます。ホット/ウォームティア、ラック、ゾーン、またはストレージタイプにノード属性を使用する場合、タイプミスがシャードを宙に浮かせる可能性があります。

たとえば、index.routing.allocation.require.box_type: high_io を持つインデックスは、node.attr.box_type: high_io で構成されたノードにのみ割り当てられます。

インデックスフィルターとノード属性を確認します:

GET /my_index/_settings?filter_path=*.settings.index.routing.allocation
GET /_cat/nodeattrs?v
GET /_cat/nodes?v&h=name,roles,disk.used_percent

インデックス設定を修正するか、適格なデータノードを追加します。マルチゾーンクラスターで割り当て認識を軽率に削除しないでください。シャードのすべてのコピーが同じ障害ドメインに配置される可能性があります。

プライマリシャードの欠落

プライマリシャードが未割り当ての場合、アクティブなプライマリを保持していたノードが消失したか、インデックスが復元されたばかりか、割り当てルールがすべての適格ノードをブロックしている可能性があります。Allocation Explain APIがElasticsearchがシャードを割り当てられない理由を教えてくれるまで、データが失われたと想定しないでください。

一般的なシナリオは次のとおりです:

  • 唯一の正常なプライマリコピーを保持していたノードがクラッシュした。
  • 割り当てフィルターがプライマリをホストできるすべてのデータノードを除外している。
  • スナップショットの復元またはインデックス作成が適格ノードを待機している。
  • 古いシャードコピーが存在するが、Elasticsearchは明示的なデータ損失の受け入れなしにはそれを昇格させない。

まず、欠落しているノードの回復、スナップショットの復元、または割り当てブロッカーの修正を試みます。強制プライマリ割り当ては、どのコピーが古いかを理解している場合、またはそのシャードのデータ損失を受け入れた場合にのみ使用します。

シャード制限

ノードあたりのシャード制限も割り当てをブロックする可能性があります。一般的な設定には、index.routing.allocation.total_shards_per_nodecluster.routing.allocation.total_shards_per_node があります。

これらの制限を確認します:

GET /_cluster/settings?include_defaults=true&filter_path=**.total_shards_per_node
GET /my_index/_settings?filter_path=*.settings.index.routing.allocation.total_shards_per_node

ノードを追加する、レプリカ数を減らす、小さなインデックスを統合する、または関連する制限を慎重に引き上げます。ノードあたりのシャードが多すぎると、ヒープの負荷が増加し、クラスター状態の操作が遅くなる可能性があります。

Allocation Explain APIを使用した診断

Allocation Explain APIは、「なぜこのシャードが割り当てられないのか」という質問に答えるための最良のツールです。

GET /_cluster/allocation/explain?pretty
{
  "index": "my_data",
  "shard": 0,
  "primary": true
}

Elasticsearchに現在未割り当てのシャードを1つ選択させるには、ボディなしでAPIを呼び出します:

GET /_cluster/allocation/explain?pretty

最初にこれらのフィールドを読み取ります:

  • can_allocate: 高レベルの回答。
  • allocate_explanation: 平易な英語の要約。
  • node_allocation_decisions: ノードごとの決定。
  • deciders: NOまたはTHROTTLEを返した正確なルール。

NO決定がブロッカーです。THROTTLE決定は通常、Elasticsearchがシャードを割り当てることができるが、同時リカバリ作業を制限していることを意味します。

安全なトラブルシューティング手順

広く始めてから、絞り込みます。

1. クラスターヘルスと未割り当てシャードを確認する

GET /_cluster/health?pretty
GET /_cat/shards?v&h=index,shard,prirep,state,unassigned.reason,node

unassigned.reasonを確認します。NODE_LEFTINDEX_CREATEDCLUSTER_RECOVEREDALLOCATION_FAILEDなどの値は、次にどこを見るべきかを示します。

2. ディスクとノードの適格性を確認する

GET /_cat/allocation?v&h=node,disk.used_percent,disk.avail,disk.total
GET /_cat/nodes?v&h=name,roles,heap.percent,ram.percent,cpu,disk.used_percent

ノードが高ウォーターマークに近い場合は、割り当て設定を変更する前にディスクの圧迫を修正します。

3. Allocation Explainを実行する

影響を受けるインデックス、シャード番号、およびプライマリ/レプリカフラグを使用します。出力は、割り当てをブロックする設定、ノード条件、または判定子を指定する必要があります。

4. 原因がわかるまでリスクの高い再ルーティングを避ける

手動再ルーティングコマンドは、特定のリカバリケースを対象としています。これらは、ディスクの圧迫、不適切なフィルター、またはレプリカが多すぎる場合の一般的な修正ではありません。

古いプライマリコピーが唯一の実用的なリカバリパスである場合、コマンドは次のようになります:

POST /_cluster/reroute
{
  "commands": [
    {
      "allocate_stale_primary": {
        "index": "index_name",
        "shard": 0,
        "node": "node_name_with_stale_copy",
        "accept_data_loss": true
      }
    }
  ]
}

accept_data_loss: trueが必要なのには理由があります。スナップショットを確認し、欠落しているノードの回復を試み、どのノードが古いコピーを保持しているかを確認した後にのみ使用してください。

5. 黄色のヘルスを個別に処理する

レプリカのみが未割り当ての場合、クラスターは引き続きプライマリデータを提供できます。まず、根本的なリソースの制約を修正します。データノードの追加、ディスクのクリア、または割り当てフィルターの修正により、通常Elasticsearchはレプリカを自動的に割り当てることができます。

レプリカなしで一時的に実行する必要がある場合は、影響を受けるインデックスのレプリカ数を減らします:

PUT /my_index/_settings
{
  "index.number_of_replicas": 0
}

これにより、Elasticsearchがそのインデックスのレプリカコピーを期待しなくなるため、ヘルスが緑色に変わる可能性があります。また、可用性が低下するため、容量を追加するか割り当てを修正した後は、レプリカを目的の値に戻してください。

割り当て問題の防止

  • ノードが高ディスクウォーターマークを超える前にアラートを発する。
  • レプリカ数と割り当て認識ルールに十分なデータノードを確保する。
  • ヒープ、データ量、およびリカバリターゲットに適合するシャード数を使用する。
  • 新しいインデックスが不適切なレプリカ数や割り当てフィルターを継承しないように、インデックステンプレートを確認する。
  • インシデントが発生する前に、ノード交換とスナップショット復元の手順をテストする。

まとめ

最も安全なパスはシンプルです:未割り当てのシャードを特定し、Allocation Explainを実行し、NOと言う判定子を修正し、データ損失のトレードオフを受け入れない限り強制割り当てを避けてください。