elasticsearch – 如何处理未分配的碎片

我的群集处于黄色状态,因为一些碎片未被分配。 该怎么办?

我试过对所有索引设置cluster.routing.allocation.disable_allocation = false ,但我认为这是行不通的,因为我使用的是1.1.1版本。

我也试过重新启动所有的机器,但是也是一样的。

任何想法?

编辑:

  • 群集统计:

     { cluster_name: "elasticsearch", status: "red", timed_out: false, number_of_nodes: 5, number_of_data_nodes: 4, active_primary_shards: 4689, active_shards: 4689, relocating_shards: 0, initializing_shards: 10, unassigned_shards: 758 } 

这些未分配的碎片实际上是来自主节点的实际碎片的未分配副本。

为了分配这些分片,您需要运行一个新的elasticsearch实例来创build一个辅助节点来承载数据副本。

编辑:有时未分配的碎片属于已被删除的索引,使他们的孤儿碎片永远不会分配,无论添加节点或不。 但在这里并不是这样!

有很多可能的原因,为什么分配不会发生:

  1. 您正在不同的节点上运行不同版本的Elasticsearch
  2. 您的群集中只有一个节点,但副本的数量设置为零以外的值。
  3. 您的磁盘空间不足。
  4. 您已禁用分片分配。
  5. 您已启用防火墙或SELinux。 在启用SELinux但未正确configuration的情况下,您将看到碎片永远停留在INITIALIZING或RELOCATING中。

作为一般规则,您可以排查这样的事情:

  1. 查看群集中的节点: curl -s 'localhost:9200/_cat/nodes?v' 。 如果只有一个节点,则需要将number_of_replicas设置为0.(请参阅ES文档或其他答案)。
  2. 查看集群中可用的磁盘空间: curl -s 'localhost:9200/_cat/allocation?v'
  3. 检查群集设置: curl 'http://localhost:9200/_cluster/settings?pretty'并查找cluster.routing设置
  4. 看看哪些分片是UNASSIGNED curl -s localhost:9200/_cat/shards?v | grep UNASS curl -s localhost:9200/_cat/shards?v | grep UNASS
  5. 尝试强制分配一个分片

     curl -XPOST -d '{ "commands" : [ { "allocate" : { "index" : ".marvel-2014.05.21", "shard" : 0, "node" : "SOME_NODE_HERE", "allow_primary":true } } ] }' http://localhost:9200/_cluster/reroute?pretty 
  6. 看看回应,看看它说什么。 会有一堆YES是可以的,然后是NO。 如果没有NO,那很可能是防火墙/ SELinux问题。

这是由默认索引设置引起的常见问题,特别是当您尝试在单个节点上进行复制时。 为了解决这个瞬态群集设置,请执行以下操作:

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

接下来,启用集群重新分配碎片(总是说完之后,您可以始终打开它):

 curl -XPUT http://localhost:9200/_cluster/settings -d ' { "transient" : { "cluster.routing.allocation.enable": true } }' 

现在请坐下来观察群集清理未分配的副本碎片。 如果您希望将来的索引生效,请不要忘记使用以下设置修改elasticsearch.yml文件并反弹集群:

 index.number_of_replicas: 0 

唯一对我有用的是改变number_of_replicas(我有2个副本,所以我把它改为1,然后改回2)。

第一:

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

然后:

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

Alcanzar的答案的前两点对我来说是这样做的,但是我不得不补充一点

 "allow_primary" : true 

像这样

 curl -XPOST http://localhost:9200/_cluster/reroute?pretty -d '{ "commands": [ { "allocate": { "index": ".marvel-2014.05.21", "shard": 0, "node": "SOME_NODE_HERE", "allow_primary": true } } ] }' 

检查每个节点上的ElasticSearch版本是否相同。 如果不是,则ES不会将索引的副本副本分配给“旧”节点。

使用@Alcanzar的答案,你可以得到一些诊断错误信息:

 curl -XPOST 'http://localhost:9200/_cluster/reroute?pretty' -d '{ "commands": [ { "allocate": { "index": "logstash-2016.01.31", "shard": 1, "node": "arc-elk-es3", "allow_primary": true } } ] }' 

结果是:

 { "error" : "ElasticsearchIllegalArgumentException[[allocate] allocation of [logstash-2016.01.31][1] on node [arc-elk-es3] [Xn8HF16OTxmnQxzRzMzrlA][arc-elk-es3][inet[/172.16.102.48:9300]]{master=false} is not allowed, reason: [YES(shard is not allocated to same node or host)] [YES(node passes include/exclude/require filters)] [YES(primary is already active)] [YES(below shard recovery limit of [2])] [YES(allocation disabling is ignored)] [YES(allocation disabling is ignored)] [YES(no allocation awareness enabled)] [YES(total shard limit disabled: [-1] <= 0)] *** [NO(target node version [1.7.4] is older than source node version [1.7.5]) *** [YES(enough disk for shard on node, free: [185.3gb])] [YES(shard not primary or relocation disabled)]]", "status" : 400 } 

如何确定ElasticSearch的版本号:

 adminuser@arc-elk-web:/var/log/kibana$ curl -XGET 'localhost:9200' { "status" : 200, "name" : "arc-elk-web", "cluster_name" : "elasticsearch", "version" : { "number" : "1.7.5", "build_hash" : "00f95f4ffca6de89d68b7ccaf80d148f1f70e4d4", "build_timestamp" : "2016-02-02T09:55:30Z", "build_snapshot" : false, "lucene_version" : "4.10.4" }, "tagline" : "You Know, for Search" } 

在我的情况下,我设置apt-get版本库不正确,他们在不同的服务器上不同步。 我纠正了所有的服务器上:

 echo "deb http://packages.elastic.co/elasticsearch/1.7/debian stable main" | sudo tee -a /etc/apt/sources.list 

然后通常:

 sudo apt-get update sudo apt-get upgrade 

并最终重启服务器。