web-dev-qa-db-ja.com

ElasticSearch:割り当てられていない断片、どのように修正しますか?

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に更新しますか?
  • 完全に他の何か?

興味深いことに、新しいインデックスが追加されたときに、そのノードが作業を開始し、クラスタの残りの部分でNiceを再生したとき、割り当てられていない断片が残っていました。

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

注:何らかの理由でシングルノードクラスタを実行している場合は、次の手順を実行する必要があります。

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

そう、私は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に設定します。

参考文献

53
Spanky

デフォルトでは、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_seccluster.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
        }
    }]
}'
106
Wilfred Hughes

この小さな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
38

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

最初:

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

その後:

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

(私はすでにこの質問に答えています)

14
Edi

以下の設定がallに設定されている場合、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
9
Nischal Kumar

私は今日、同じ問題の断片の割り当てで立ち往生しています。そのスクリプトは Wです。 Andrew Loe 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"変数には適切な値を指定する必要があります。

6
Splanger

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

この記事を見てください。 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分ごとにチェックします。

5
manyways

誰かに役立つかもしれませんが、私は同じ問題を抱えていて、ログが大きくなりすぎてストレージスペースが足りなくなったことが原因でした。

誰かに役立つことを願っています! :)

4

私の場合、新しいインデックスを作成すると、デフォルトnumber_of_replicasは1に設定されています。また、私のクラスタ内のノード数は1つのみであったため、レプリカを作成するための余分なノードはありませんでした。つまり、設定プロパティでインデックスを作成し、number_of_replicasを0に設定した場合うまくいった。お役に立てれば。

PUT /customer
{
    "settings": {
        "number_of_replicas": 0
    }
}
3
Apoorv Nag

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

しかし、@Wilfred Hughesによる回答(transientを使用して "cluster.routing.allocation.enable"を "all"に設定)にすると、次の文でエラーが発生しました。

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

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

3
Jörg Rech

私もこの問題を抱えていました、そして私はそれを解決する簡単な方法を見つけました。

  • 割り当てられていない断片のインデックスを取得する

    $ 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

  • それから断片をもう一度チェックしてください。割り当てられていない断片はすべて消えます。
3
user3391471

私もこの状況に遭遇し、ついにそれを直しました。

まず、自分の状況について説明します。 ElasticSearchクラスターに2つのノードがあり、それらは互いに見つけることができますが、設定 "number_of_replicas"でインデックスを作成したとき:2、 "number_of_shards" 5、ESは黄色い信号を示し、unassigned_shardsは5です。

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

2
Armstrongya

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

1
alwe

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

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

# 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
Daniel Knowlton

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

.....

どのインデックスが赤で実行されているのかを確認するために、インデックスリストを調べることから始めました。

"get /_cat/shards?h=[INDEXNAME],shard,prirep,state,unassigned.reason"

また、シャードがALLOCATION_FAILED状態で動かなくなっていたため、上記の再試行を実行すると割り当てが再試行されました。

1
ScottFoster1000

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

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


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

さて、今回はノードを追加するだけではうまくいかないようです(数分待ってから)ので、私はREST AP​​Iを調べ始めました。

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
nobar

破損したシャードを処理する場合、レプリケーション係数を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にハードコードされます。

0
bonzofenix

割り当てられていない断片を削除するか、手動でそれらを特定のデータノードに割り当てようとしました。割り当てられていない破片が出現し続け、健康状態が何度も「赤」になっていたため、うまくいきませんでした。それから、データノードの1つが「再起動」状態で動かなくなったことに気付きました。データノードの数を減らして殺しました。問題はもう再現できません。

0
thepolina

多分助けになるかもしれませんが、埋め込みモードでESを実行しようとしたときにこの問題が発生しました。修正したのは、ノードにローカル(true)が設定されていることを確認することでした。

0
JARC

私は最初にちょうど増加しました

"index.number_of_replicas"

1ずつ(ノードが同期されるまで待機)、その後1ずつ減少させます。これにより、未割り当ての断片が事実上削除され、データが失われることなくクラスターが再び緑色になります。

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

お役に立てれば。

0
Yusuf Demirag

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

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

これは、割り当てられていない断片の根本的な原因となる可能性があります。

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

0
Marc Tamsky

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

私の場合、それはデータノード上の空きディスクスペースの不足によって引き起こされました。割り当てられていない断片は、再起動後にまだデータノード上にありますが、マスターによって認識されていません。

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

0