如果只有1个单节点es,却在index中的settings中设置了replica大于0,那么这个索引的replica shard就会成为unassigned shards
curl http://hostIP|hostName:9200/_cat/shards |grep UNASSIGNED
通过cluster-allocation-explain API查看集群索引分配执行过程,会有类似the shard cannot be allocated to the same node on which a copy of the shard already exists的报错
curl -XGET http://hostIP|hostName:9200/_cluster/allocation/explain?pretty
可手动设置索引的副本数为0
curl -XPUT -H 'Content-Type:application/json' http://hostIP|hostName:9200/indexName/_settings -d '
{
"index.number_of_replicas" : "0"
}'
如果在生产环境有很多索引出现UNASSIGNED情况,可以先关闭一些暂时不需要搜索的数据,加快恢复速度
例如基于索引名称的时间范围选择关闭
for i in `curl -s localhost:9200/_cat/indices?h=i | grep 2019.06`;do curl -XPOST localhost:9200/$i/_close;done
如果确认相关索引下没有生产数据,可删除索引
curl -XDELETE http://hostIP|hostName:9200/indexName
如果出现shard has exceeded the maximum number of retries报错,可以开启重试
curl -XPOST http://127.0.0.1:9200/_cluster/reroute?retry_failed=true
否则需要进一步分析是哪种情况导致了,再对索引进行修复
- Shard allocation is purposefully delayed
- Too many shards, not enough nodes
- You need to re-enable shard allocation
- Shard data no longer exists in the cluster
- Low disk watermark
- Multiple Elasticsearch versions
Shard allocation暂时性延迟
当节点意外脱离集群时,master会暂时延迟分片重新分配,以避免脱离集群的节点在能够迅速(默认为一分钟)恢复的情况下,进行重新平衡分片的浪费资源。 这种情况日志通常会打印如下信息
动态修改延迟期限[TIMESTAMP][INFO][cluster.routing] [MASTER NODE NAME] delaying allocation for [54] unassigned shards, next check in [1m]
curl -XPUT 'hostIP|hostName:9200/indexName/_settings' -d
'{
"settings": {
"index.unassigned.node_left.delayed_timeout": "30s"
}
}'
shards过多,节点不够
当节点加入和离开集群时,master点会自动进行分配重平衡,以确保分片的多个副本未分配给同一节点。也就是说,master不会将主分片分配至其副本分片所在的节点,也不会将同一分片的两个副本分配给同一节点。此时, 如果没有足够的节点来可以分配分片,则分片可能会停留在unassigned状态。因此,需要确保每个索引的主分片的副本数小于集群的节点数
N >= R + 1
N:集群节点数
R:主分片的最大副本数分片分配未恢复启用
默认情况下所有节点都启用分片分配,但在更新升级时进行滚动重启前为避免不必要的资源浪费,可能禁用了分片分配却忘记重新启用。
更新Cluster Setting API启用集群分片分配curl -XPUT 'hostIP|hostName:9200/_cluster/settings' -d
'{ "transient":
{ "cluster.routing.allocation.enable" : "all"
}
}'
分片数据丢失
一种情况是某个索引的主分片没有任何副本,因为某种原因该分片所在的节点在分片的数据被复制之前脱离了集群,master 在全局集群状态文件中能够检测到分片,但却无法在集群中找到分片的数据。
另一种可能的情况节点在重启时可能遇到意外, 通常当节点恢复其与群集的连接时,它会将有关其磁盘分片的信息中传递给master,由master分配将unassigned分片转换为assigned/started。 这个过程由于磁盘损坏等原因失败时,分片可能保持unassigned状态。在这种情况下,可以尝试恢复异常节点并重新加入群集(并且不强制分配主分片),或者使用Reroute API强制分配分片并且用原始数据源或者备份重新索引丢失的数据。
如果要分配unassigned主分片,确保在请求中添加“allow_primary”:“true”标志 ``` curl -XPOST ‘hostIP|hostName:9200/_cluster/reroute’ -d ‘{ “commands” :
}’[ { "allocate" :
{ "index" : "indexName", "shard" : 0, "node": "nodeName", "allow_primary": "true" }
}]
否则可能会出现如下报错
“reason”:”[allocate] trying to allocate a primary shard [constant-updates][0], which is disabled”},”status”:400}
需要注意的是强制分配主分片后将分配[一个“空”分片](https://www.elastic.co/guide/en/elasticsearch/reference/5.4/cluster-reroute.html)。 如果包含原始主分片数据的节点重新加入群集,那么该节点上的数据将被[新创建的(空)主分片覆盖](https://github.com/elastic/elasticsearch/issues/16113),因为“空”分片被认为是数据的“较新”版本。如果数据被覆盖,则需要从[快照或备份](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html)中重新索引丢失的数据,进行还。
<a name="om5UE"></a>
### 磁盘可用空间不足
如果没有足够的磁盘空间节点,master可能无法分配分片(默认不会将分片分配给磁盘使用率超过85%节点)。<br />使用[Cat API](https://www.elastic.co/guide/en/elasticsearch/reference/current/cat-allocation.html) 可以查看各节点磁盘的使用情况
curl -s ‘hostIP|hostName:9200/_cat/allocation?v’
如果磁盘空间不足,需要迁移分片或者扩容磁盘,如果是5TB以上的大容量,可以使用Cluster Update Settings API更改[cluster.routing.allocation.disk.watermark.low或cluster.routing.allocation.disk.watermark.high](https://www.elastic.co/guide/en/elasticsearch/reference/5.4/disk-allocator.html)<br />调高阈值
curl -XPUT ‘hostIP|hostName:9200/_cluster/settings’ -d
‘{
“transient”: {
“cluster.routing.allocation.disk.watermark.low”: “90%”
}
}’
```
如果希望在群集重新启动时保持配置更改,请将“transient”替换为“persistent”,或者在配置文件中设置。 可以选择使用gb或%来更新设置,需要注意%是指已用磁盘空间,而gb是指可用磁盘空间”。
集群包含多版本节点
在集群进行滚动升级时,集群中包含多个版本的节点,master不会将主分片的副本分配给低于主分片所在节点版本的节点
https://www.datadoghq.com/blog/elasticsearch-unassigned-shards/