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一个辅助节点来承载数据副本。
编辑:有时未分配的碎片属于已被删除的索引,使他们的孤儿碎片永远不会分配,无论添加节点或不。 但在这里并不是这样!
有很多可能的原因,为什么分配不会发生:
- 您正在不同的节点上运行不同版本的Elasticsearch
- 您的群集中只有一个节点,但副本的数量设置为零以外的值。
- 您的磁盘空间不足。
- 您已禁用分片分配。
- 您已启用防火墙或SELinux。 在启用SELinux但未正确configuration的情况下,您将看到碎片永远停留在INITIALIZING或RELOCATING中。
作为一般规则,您可以排查这样的事情:
- 查看群集中的节点:
curl -s 'localhost:9200/_cat/nodes?v'
。 如果只有一个节点,则需要将number_of_replicas
设置为0.(请参阅ES文档或其他答案)。 - 查看集群中可用的磁盘空间:
curl -s 'localhost:9200/_cat/allocation?v'
- 检查群集设置:
curl 'http://localhost:9200/_cluster/settings?pretty'
并查找cluster.routing
设置 - 看看哪些分片是UNASSIGNED
curl -s localhost:9200/_cat/shards?v | grep UNASS
curl -s localhost:9200/_cat/shards?v | grep UNASS
-
尝试强制分配一个分片
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
-
看看回应,看看它说什么。 会有一堆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
并最终重启服务器。