notebook

都内でWEB系エンジニアやってます。

elasticsearch unassignedになってしまったシャードの割り当て

elasticsearchを運用していて、たまにshardの割り当てがうまくいかずにずっとunassignedのままになってしまうシャードが出てきた時

一件づつならelasticsearchのAPIを利用して下記コマンドで解決できます

curl -XPOST 'http://10.0.21.60:9200/_cluster/reroute' -d '{
  "commands": [{
    "allocate": {
      "index": "backend.error_log-2015-07-13",
      "shard": 4,
      "node": "10.0.21.61",
      "allow_primary": true
    }
  }]
}'

ただ、数が沢山あった場合には気分がめいってしまいますね

curatorにそのような機能がないか見てみたのですがそれらしい記述を見つけることができなかったのでスクリプトで実装しました

  • reroute_unassigned_shards.sh
#/bin/sh

APIURL="http://192.168.20.11:9200"

MASTER_NODE="192.168.20.11"

NODES=( 192.168.20.11 192.168.20.12 192.168.20.13 )

function reroute_shards {
  unassigned_shards="$(curl -s -XGET $APIURL/_cat/shards | grep UNASSIGNED | awk '{print $1,$2,$3}')"

  if [ "$unassigned_shards" == "" ]; then
    exit
  fi

  echo -e "$unassigned_shards" | while read line
  do
    post_api "$line"
  done
}

function post_api {
  line=$1

  set -- $line
  index=$1
  number=$2
  shard=$3

  {{ 'i=`expr $RANDOM % ${#NODES[@]}`' }}
  node=${NODES[$i]}

  if [ $3 == "p" ]; then
    echo "index: $index, number: $number, $shard: $shard, to: $node"
    curl -s -XPOST "$APIURL/_cluster/reroute" -d "{
  \"commands\": [{
    \"allocate\": {
      \"index\": \"$index\",
      \"shard\": \"$number\",
      \"node\": \"$node\",
      \"allow_primary\": \"true\"
    }
  }]
}"
  fi
}

reroute_shards

cat APIでシャードの情報を取得できるので、"unassigned" なシャードに対してreroute APIを叩かせています

割り当てるノードは全ノードの中からランダムで決まるようにしています

これで多少は楽できますね!