ElasticSearch:未割り当てのシャード、修正方法?


165

4つのノードを持つESクラスターがあります。

number_of_replicas: 1
search01 - master: false, data: false
search02 - master: true, data: true
search03 - master: false, data: true
search04 - master: false, data: true

私はsearch03を再起動する必要があり、戻ってきたときに問題なくクラスターに再参加しましたが、割り当てられていない7つのシャードが残っていました。

{
  "cluster_name" : "tweedle",
  "status" : "yellow",
  "timed_out" : false,
  "number_of_nodes" : 4,
  "number_of_data_nodes" : 3,
  "active_primary_shards" : 15,
  "active_shards" : 23,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 7
}

現在、クラスターは黄色の状態です。この問題を解決する最良の方法は何ですか?

  • シャードを削除(キャンセル)しますか?
  • シャードを別のノードに移動しますか?
  • ノードにシャードを割り当てますか?
  • 「number_of_replicas」を2に更新しますか?
  • 他に完全に何か?

興味深いことに、新しいインデックスが追加されると、そのノードはそのインデックスで作業を開始し、クラスターの残りの部分でうまく機能しましたが、割り当てられていないシャードが残ったままになっています。

質問に従ってください:これを最初に起こすために何か間違ったことをしていますか?ノードを再起動したときにこのように動作するクラスターには、あまり自信がありません。

注:何らかの理由で単一ノードのクラスターを実行している場合は、単に次の操作を行う必要がある場合があります。

curl -XPUT 'localhost:9200/_settings' -d '
{
    "index" : {
        "number_of_replicas" : 0
    }
}'

回答:


117

デフォルトでは、Elasticsearchはシャードをノードに動的に再割り当てします。ただし、シャード割り当てを無効にした場合(おそらく、ローリングリスタートを実行し、再度有効にするのを忘れた場合)、シャード割り当てを再度有効にすることができます。

# v0.90.x and earlier
curl -XPUT 'localhost:9200/_settings' -d '{
    "index.routing.allocation.disable_allocation": false
}'

# v1.0+
curl -XPUT 'localhost:9200/_cluster/settings' -d '{
    "transient" : {
        "cluster.routing.allocation.enable" : "all"
    }
}'

その後、Elasticsearchは通常どおり断片を再割り当てします。これは遅くなる可能性があります。上げることindices.recovery.max_bytes_per_secを検討しcluster.routing.allocation.node_concurrent_recoveries、スピードアップしてください。

それでも問題が解決しない場合は、おそらく別の問題が考えられます。Elasticsearchログでエラーを確認してください。あなたが表示された場合EsRejectedExecutionException、あなたのスレッドプールが小さすぎる可能性があります

最後に、再ルーティングAPIを使用して、シャードをノードに明示的に再割り当てできます

# Suppose shard 4 of index "my-index" is unassigned, so you want to
# assign it to node search03:
curl -XPOST 'localhost:9200/_cluster/reroute' -d '{
    "commands": [{
        "allocate": {
            "index": "my-index",
            "shard": 4,
            "node": "search03",
            "allow_primary": 1
        }
    }]
}'

3
私がそれをしたとき、私は得ました:{ "error" : "ElasticsearchIllegalArgumentException[[allocate] failed to find [logstash-2015.01.05][1] on the list of unassigned shards]", "status" : 400 } シャードはESヘッドの未割り当ての1つであることがわかります
wjimenez5271

ちなみに、割り当てられていないものとしてリストされている他のシャードが機能し、残りのシャードは自分で修正しました。
wjimenez5271 2015年

これは素晴らしいアドバイスです。
Yehosef 2015

1
リリース5.0以降、「allocate」コマンドはより多くのオプションを提供するように変更されました -上記の例は「allocate_empty_primary」になり、「allow_primary」パラメーターが省略されています。
jmb 2017年

4
-H 'Content-Type: application/json'エラーが発生した場合は追加する必要がありますContent-Type header [application/x-www-form-urlencoded] is not supported
luckydonald

56

はい、ESサポートの助けを借りて解決しました。すべてのノード(または問題の原因と思われるノード)のAPIに次のコマンドを発行します。

curl -XPUT 'localhost:9200/<index>/_settings' \
    -d '{"index.routing.allocation.disable_allocation": false}'

<index>犯人であるとあなたが信じる指数はどこですか わからない場合は、これをすべてのノードで実行します。

curl -XPUT 'localhost:9200/_settings' \
    -d '{"index.routing.allocation.disable_allocation": false}'

また、この行をyaml設定に追加しました。それ以降、サーバー/サービスの再起動で問題が発生することはありません。シャードはすぐに再割り当てされました。

FWIW、よく尋ねられる質問に答えるには、マシンのRAMが60G未満でない限り、MAX_HEAP_SIZEを30Gに設定します。この場合、使用可能なメモリの半分に設定します。

参考文献


2
バージョン1.1.1でこれを解決するには、cluster.routing.allocation.enable = noneを使用する必要がありますか?
user3175226

1
割り当てを無効には、もはや、少なくともではない11月20のように、そこに文書化されていない

3
ルーティング割り当てはクラスター全体の設定であるため、コマンドを送信するノードは関係ないことに注意してください。
Wilfred Hughes

両方をes ymlファイルに追加しました。index.routing.allocation.disable_allocation : false cluster.routing.allocation.enable: noneしかし、まだ割り当てられていない破片が表示されています。理由は何ですか?
Bagui、2015年

1
:バージョン6.8では、私はエラーを取得{ "type": "illegal_argument_exception", "reason": "unknown setting [index.routing.allocation.disable_allocation] please check that any required plugins are installed, or check the breaking changes documentation for removed settings" } ],
Janacミーナ

39

この小さなbashスクリプトはブルートフォースの再割り当てを行うため、データを失う可能性があります。

NODE="YOUR NODE NAME"
IFS=$'\n'
for line in $(curl -s 'localhost:9200/_cat/shards' | fgrep UNASSIGNED); do
  INDEX=$(echo $line | (awk '{print $1}'))
  SHARD=$(echo $line | (awk '{print $2}'))

  curl -XPOST 'localhost:9200/_cluster/reroute' -d '{
     "commands": [
        {
            "allocate": {
                "index": "'$INDEX'",
                "shard": '$SHARD',
                "node": "'$NODE'",
                "allow_primary": true
          }
        }
    ]
  }'
done

魅力のように働いた。ありがとう!
Paulo Pires、2015年

次のエラーが発生しました:<br> {"error": "JsonParseException [Unexpected characte r( '、'(code 44)):expected a valid value(number、String、array、object、 'true'、 'false' or 'null')\ n at [ソース:[B @ 3b1fadfb; line:6、column:27]] "、" status ":500} <br>修正するにはどうすればいいですか
biolinh

トンありがとう!貴重な時間を節約できました!!
Sathish '17年

スクリプトがエラーをスローする:{"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406}{"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406}
Janac Meena

17

私にとってうまくいった唯一のことは、number_of_replicasを変更することでした(2つのレプリカがあったため、1に変更してから2に戻しました)。

最初:

PUT /myindex/_settings
{
    "index" : {
        "number_of_replicas" : 1
     }
}

次に:

PUT /myindex/_settings
{
    "index" : {
        "number_of_replicas" : 2
     }
}

(私はすでにこの質問でそれを理解していました)


9

以下の設定がすべてに設定されている場合、Elasticsearchは自動的にシャードを割り当てます。この設定は、rest apiおよび cluster.routing.allocation.enable:allを使用して設定できます

以下の設定を適用した後でも、esが自動的にシャードを割り当てることができない場合は、自分でシャードを強制的に割り当てる必要があります。これのES公式リンク

クラスター全体に割り当てられていないすべてのシャードを強制的に割り当てるスクリプトを作成しました。

配列の下には、割り当てられていないシャードのバランスを取るノードのリストが含まれています

#!/bin/bash
array=( node1 node2 node3 )
node_counter=0
length=${#array[@]}
IFS=$'\n'
for line in $(curl -s 'http://127.0.0.1:9200/_cat/shards'|  fgrep UNASSIGNED); do
    INDEX=$(echo $line | (awk '{print $1}'))
    SHARD=$(echo $line | (awk '{print $2}'))
    NODE=${array[$node_counter]}
    echo $NODE
    curl -XPOST 'http://127.0.0.1:9200/_cluster/reroute' -d '{
        "commands": [
        {
            "allocate": {
                "index": "'$INDEX'",
                "shard": '$SHARD',
                "node": "'$NODE'",
                "allow_primary": true
            }
        }
        ]
    }'
    node_counter=$(((node_counter)%length +1))
done

このスクリプトは機能しませんでした。つまり、実行した後も、UNNASSIGNEDシャードが残っていました。
クリスF

@ChrisF 1行目では、node1、node2、node3を実際のノード名に置き換える必要があります。curl localhost:9200 / _cat / nodesで取得できます。
シディ2017年

6

今日は、シャードの割り当てについて同じ問題を抱えています。W.アンドリューロウIIIが彼の回答で提案したスクリプト は私には機能しなかったので、少し修正して、最終的に機能しました。

#!/usr/bin/env bash

# The script performs force relocation of all unassigned shards, 
# of all indices to a specified node (NODE variable)

ES_HOST="<elasticsearch host>"
NODE="<node name>"

curl ${ES_HOST}:9200/_cat/shards > shards
grep "UNASSIGNED" shards > unassigned_shards

while read LINE; do
  IFS=" " read -r -a ARRAY <<< "$LINE"
  INDEX=${ARRAY[0]}
  SHARD=${ARRAY[1]}

  echo "Relocating:"
  echo "Index: ${INDEX}"
  echo "Shard: ${SHARD}"
  echo "To node: ${NODE}"

  curl -s -XPOST "${ES_HOST}:9200/_cluster/reroute" -d "{
    \"commands\": [
       {
         \"allocate\": {
           \"index\": \"${INDEX}\",
           \"shard\": ${SHARD},
           \"node\": \"${NODE}\",
           \"allow_primary\": true
         }
       }
     ]
  }"; echo
  echo "------------------------------"
done <unassigned_shards

rm shards
rm unassigned_shards

exit 0

さて、私は一種のBashの第一人者ではありませんが、スクリプトは実際に私の場合に役立ちました。「ES_HOST」および「NODE」変数に適切な値を指定する必要があることに注意してください。


:残念ながらES5xは互換性破ったelastic.co/guide/en/elasticsearch/reference/5.1/...
Fawix

2
ES5xと仕事に上記のスクリプトのために交換するallocateallocate_empty_primaryして交換\"allow_primary\": trueして\"accept_data_loss\": true
Fawix

取得{"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406}さえFawixの提案適用後
Janacミーナ

6

私の場合、ハードディスク容量の上限に達しました。

この記事を見てください:https : //www.elastic.co/guide/en/elasticsearch/reference/current/disk-allocator.html

基本的に、私は走った:

PUT /_cluster/settings
{
  "transient": {
    "cluster.routing.allocation.disk.watermark.low": "90%",
    "cluster.routing.allocation.disk.watermark.high": "95%",
    "cluster.info.update.interval": "1m"
  }
}

ハードディスク容量が90%未満の場合は割り当てられ、ハードディスク容量が95%を超える場合はクラスター内の別のマシンにシャードを移動します。1分ごとにチェックします。


4

多分それは誰かを助けるかもしれませんが、私は同じ問題を抱えていました、そしてそれはログがあまりに大きくなりすぎたことによって引き起こされたストレージスペースの不足が原因でした。

それが誰かを助けることを願っています!:)


4

私の場合、新しいインデックスを作成すると、デフォルトのnumber_of_replicasが1に設定されます。また、クラスター内のノードの数は1つだけだったため、レプリカを作成するための追加のノードはなかったため、ヘルスは黄色に変わりました。そのため、settingsプロパティを使用してインデックスを作成し、number_of_replicasを0に設定すると、 正常に動作しました。お役に立てれば。

PUT /customer
{
    "settings": {
        "number_of_replicas": 0
    }
}

3

私は同じ問題を抱えていましたが、根本的な原因はバージョン番号の違いでした(2つのノードでの1.4.2(問題あり)と2つのノードでの1.4.4(ok))。最初と2番目の回答(「index.routing.allocation.disable_allocation」をfalseに設定し、「cluster.routing.allocation.enable」を「all」に設定)は機能しませんでした。

ただし、@ Wilfred Hughesの回答(「cluster.routing.allocation.enable」を「transient」を使用して「all」に設定)を使用すると、次のステートメントでエラーが発生しました。

[NO(ターゲットノードのバージョン[1.4.2]はソースノードのバージョン[1.4.4]より古い)]

古いノードを1.4.4に更新した後、これらのノードは他の正常なノードとResncを開始しました。


3

私もこの問題を抱えていましたが、簡単に解決できる方法を見つけました。

  • 割り当てられていないシャードのインデックスを取得する

    $ curl -XGET http://172.16.4.140:9200/_cat/shards
    
  • キュレーターツールをインストールし、それを使用してインデックスを削除する

    $ curator --host 172.16.4.140 delete indices --older-than 1 \
           --timestring '%Y.%m.%d' --time-unit days --prefix logstash
    

    注:私の場合、インデックスはその日のlogstashです2016-04-21

  • 次に、シャードをもう一度確認します。割り当てられていないシャードはすべて消えます。

1
@sim、私の回答を編集していただきありがとうございます。私は編集が非常に苦手なので、もっと注意を払います。
user3391471 2016年

私にとって、それはだった:curator_cli --host 127.0.0.1 delete_indices --filter_list '[{"filtertype":"pattern","kind":"prefix","value":"logstash-"}]'
GAUI

2

私もこの状況を満たし、最終的にそれを修正しました。

最初に、私の状況について説明します。ElasticSearchクラスターに2つのノードがありますが、お互いを見つけることができますが、「number_of_replicas」の設定でインデックスを作成した場合:2、「number_of_shards」:5、ESは黄色の信号を示し、unassigned_shardsは5です。

この問題は、number_of_replicasの値を1に設定すると、すべて問題ないために発生します。


4
レプリカの数は、常にノードの数のN-1にする必要があります。したがって、2つのノードがあるシナリオでは、ノードの1つにプライマリシャードが含まれ、他のノードにはレプリカがあるため、レプリカの数は1に設定する必要があります。N= 2、N-1 = 1
slm

1

私の場合、古い共有を持つ古いノードがクラスターに参加していたため、古いノードをシャットダウンして、割り当てられていないシャードのインデックスを削除する必要がありました。


1

上記の提案をいくつか試しましたが、残念ながらどれもうまくいきませんでした。アプリがエラーを書き込む、より低い環境に「ログ」インデックスがあります。単一ノードのクラスターです。私にとってそれを解決したのは、ノードのYML構成ファイルを確認し、デフォルトの設定 "gateway.expected_nodes:2"がまだ残っていることを確認することでした。これにより、他の設定が上書きされていました。このノードにインデックスを作成するときはいつでも、5つのシャードのうち3つをファントムの2番目のノードに分散しようとします。したがって、これらは未割り当てとして表示され、最初の唯一のノードに移動することはできません。

解決策は、構成を編集し、設定 "gateway.expected_nodes"を1に変更して、クラスター内で見つからない兄弟を探して終了し、Elasticサービスインスタンスを再起動することでした。また、インデックスを削除して、新しいインデックスを作成する必要がありました。インデックスを作成した後、すべてのシャードが最初の唯一のノードに表示され、割り当て解除されたものはありませんでした。

# Set how many nodes are expected in this cluster. Once these N nodes
# are up (and recover_after_nodes is met), begin recovery process immediately
# (without waiting for recover_after_time to expire):
#
# gateway.expected_nodes: 2
gateway.expected_nodes: 1

1

私にとって、これは開発コンソールからこれを実行することで解決されました: "POST / _cluster / reroute?retry_failed"

.....

まずインデックスリストを見て、どのインデックスが赤かを確認してから実行しました。

「/_cat/shards?h=[INDEXNAME],shard,prirep,state,unassigned.reasonを取得」

また、シャードがALLOCATION_FAILED状態でスタックしていることがわかったため、上記の再試行を実行すると、割り当てが再試行されました。


バージョン5.6.3以降、コマンドは/_cat/shards/[INDEXNAME]?h=,shard,prirep,state,unassigned.reasonを取得する必要があります
fasantos

0

役立つかもしれませんが、組み込みモードでESを実行しようとしたときにこの問題が発生しました。修正は、ノードにlocal(true)が設定されていることを確認することでした。


0

シャードが割り当てられていないもう1つの理由として、クラスターでElasticsearchバイナリの複数のバージョンが実行されていることが考えられます。

最新バージョンから前のバージョンへのシャードレプリケーションは機能しません

これは、割り当てられていないシャードの根本的な原因になる可能性があります。

Elastic Documentation-ローリングアップグレードプロセス


0

私はまったく同じ問題に遭遇しました。elasticsearchを再起動する前に一時的にシャード割り当てをfalseに設定することでこれを防ぐことができますが、割り当てられていないシャードがすでに存在する場合、これは修正されません。

私の場合、それはデータノードの空きディスク領域の不足が原因でした。未割り当ての断片は、再起動後もデータノード上にありますが、マスターによって認識されません。

ディスクからノードの1つをクリーニングするだけで、レプリケーションプロセスが開始されました。すべてのデータを1つのデータノードから他のデータノードにコピーする必要があるため、これはかなり遅いプロセスです。


0

割り当てられていないシャードを削除するか、手動で特定のデータノードに割り当てようとしました。割り当てられていないシャードが表示され続け、ヘルスステータスが何度も「赤」になったため、機能しませんでした。次に、データノードの1つが「再起動」状態のままになっていることに気付きました。データノードの数を減らして殺しました。問題は再現しません。


0

自己修復されていないように見える、割り当てられていないシャードを持つ2つのインデックスがありました。私は最終的に、一時的に余分なデータノードを追加することでこれを解決しました[1]。インデックスが正常になり、すべてが緑色に安定した後、余分なノード削除すると、システムは(再度)リバランスして正常な状態に落ち着きました。

一度に複数のデータノードを強制終了しないようにすることをお勧めします(これが私がこの状態になった方法です)。おそらく、少なくとも1つのシャードのコピー/レプリカを保存できませんでした。幸い、Kubernetesはディスクストレージを保持し、データノードを再起動したときにそれを再利用しました。


...時間が経ちました...

さて、今回はノードを追加するだけでは機能しないようでした(何かが発生するまで数分待った後)ので、REST APIを試し始めました。

GET /_cluster/allocation/explain

これはで私の新しいノードを示しました"decision": "YES"

ちなみに、既存のすべてのノードにはが"decision": "NO"原因"the node is above the low watermark cluster setting"でした。したがって、これはおそらく、以前に対処したケースとは異なるケースでした。

それから私は、次のような単純なPOST製[2] 本文なしでギアに物事を蹴りました ...

POST /_cluster/reroute

その他の注意事項:


[1]十分なヘッドルームがある場合、Kubernetesで実行するのは非常に簡単です。ダッシュボードを介してステートフルセットをスケールアウトするだけです。

[2] Kibanaの「Dev Tools」インターフェイスを使用して、SSH / execシェルを気にする必要はありませんでした。


0

私は最初に増加しました

「index.number_of_replicas」

1ずつ(ノードが同期されるまで待機)、その後1ずつ減らします。これにより、割り当てられていないシャードが実質的に削除され、クラスターはデータを失うリスクなしに再びグリーンになります。

もっと良い方法があると思いますが、これは私にとっては簡単です。

お役に立てれば。


0

破損したシャードを処理する場合、レプリケーション係数を0に設定してから、元の値に戻すことができます。これにより、破損しているすべてのシャードではなくてもほとんどがクリアされ、クラスター内の新しいレプリカが再配置されます。

割り当てられていないレプリカのインデックスを設定して、レプリケーション係数0を使用します。

curl -XGET http://localhost:9200/_cat/shards |\
  grep UNASSIGNED | grep ' r ' |\
  awk '{print $1}' |\
  xargs -I {} curl -XPUT http://localhost:9200/{}/_settings -H "Content-Type: application/json" \
  -d '{ "index":{ "number_of_replicas": 0}}'

それらを1に戻します。

curl -XGET http://localhost:9200/_cat/shards |\
  awk '{print $1}' |\
  xargs -I {} curl -XPUT http://localhost:9200/{}/_settings -H "Content-Type: application/json" \
  -d '{ "index":{ "number_of_replicas": 1}}'

注:インデックスごとに異なるレプリケーション係数がある場合は、これを実行しないでください。これにより、すべてのインデックスのレプリケーション係数が1にハードコードされます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.