背景是对线上的es7集群(这里简称为集群A)进行动态扩容,A集群配置3个node节点,在进行节点重启时误重启了其他集群(这里简称为集群B)废弃的节点,导致AB两个集群不可用,red状态。
现象
- AB两个集群red状态
- A集群有节点offline
- B集群节点都online,但多个index的主副分片unassigned
解决办法
这里先交代下最后的解决办法:
A集群
对于A集群,找到正确的es安装地址,动态扩容后重启即可。
B集群
而对于B集群就比较复杂些,着重解决shard unassigned问题。
- 检查哪些index的shard出现unassigned问题
可以通过命令:GET _cat/shards?h=index,shard,prirep,state,unassigned.reason
定位到出现问题的index。如果你平常是使用kibana来查询监控集群的,当集群status=red时,kibana是无法连接到集群的,也就无法使用Dev Tools。这里推荐你使用Cerebro,一款提供对于ElasticSearch更加友好的可视化操作支持的工具。直接执行cat apis - 三思而后行
要从出现问题的index角度出发,如果是无关紧要或者是已经下线不在使用的,可以直接删除;反之删除index操作要慎重。
根据unassigned.reason具体问题具体分析,根据官方的解释有如下:
- INDEX_CREATED:由于创建索引的API导致未分配。
- CLUSTER_RECOVERED :由于完全集群恢复导致未分配。
- INDEX_REOPENED :由于打开open或关闭close一个索引导致未分配。
- DANGLING_INDEX_IMPORTED :由于导入dangling索引的结果导致未分配。
- NEW_INDEX_RESTORED :由于恢复到新索引导致未分配。
- EXISTING_INDEX_RESTORED :由于恢复到已关闭的索引导致未分配。
- REPLICA_ADDED:由于显式添加副本分片导致未分配。
- ALLOCATION_FAILED :由于分片分配失败导致未分配。
- NODE_LEFT :由于承载该分片的节点离开集群导致未分配。
- REINITIALIZED :由于当分片从开始移动到初始化时导致未分配(例如,使用影子shadow副本分片)。
- REROUTE_CANCELLED :作为显式取消重新路由命令的结果取消分配。
- REALLOCATED_REPLICA :确定更好的副本位置被标定使用,导致现有的副本分配被取消,出现未分配。
根据目前查询的结果来看,我是属于DANGLING_INDEX_IMPORTED
我做了哪些尝试
❎由于出现故障,导致分配分片的5次(默认)重试机会用完了,所以不会再自动分配,需要进行retry
POST /_cluster/reroute?retry_failed=true
❎调整index的副本数为0
curl -XPUT 'localhost:9200/<INDEX_NAME>/_settings' -d '{"number_of_replicas": 0}'
❎调整index的刷新时间为5m
curl -XPUT 'localhost:9200/<INDEX_NAME>/_settings' -d ' { "settings": { "index.unassigned.node_left.delayed_timeout": "5m" } }'
✅手动分配分片,将主分片分配(只丢失部分数据,出现问题的index均为不在使用的)
POST _cluster/reroute
{
"commands": [
{
"allocate_stale_primary": {
"index": "index_name",
"shard": 4,
"node": "node1",
"accept_data_loss" : true
}
}
]
}
分析
搜罗下网上归纳的出现unassigned的主要原因,建议直接阅读原文:How to Resolve Unassigned Shards in Elasticsearch | Datadog
补充下
不同版本的es的reroute语法
ES2.x的reroute命令:
curl -XPOST 'localhost:9200/_cluster/reroute' -d '{
"commands" : [ {
"move" :
{
"index" : "test", "shard" : 0,
"from_node" : "node1", "to_node" : "node2"
}
},
{
"allocate" : {
"index" : "test", "shard" : 1, "node" : "node3",
"allow_primary":true (表示接受主分片数据丢失)
}
}
]
}'
ES5.x升级之后,已经把主分片的恢复和副本的恢复进行了区分,Cluster Reroute | Elasticsearch Reference [5.6] | Elastic
curl -XPOST 'localhost:9200/_cluster/reroute' -d '{
"commands" : [ {
"move" :
{
"index" : "test", "shard" : 0,
"from_node" : "node1", "to_node" : "node2"
}
},
{
"allocate_replica" : {
"index" : "test", "shard" : 1, "node" : "node3"
}
},
{
"allocate_empty_primary": {
"index" : "test", "shard" : 1, "node" : "node3",
"accept_data_loss":true (接受数据丢失)
}
}
]
}'
不同情况下手动分配分片的流程
- red情况下手动分配主分配操作流程
- 先查询未分配的主分片原来是在哪个节点上
GET /order_orderlist/_shard_stores
- 将主分片分配(只丢失部分数据)
- 先查询未分配的主分片原来是在哪个节点上
POST _cluster/reroute
{
"commands": [
{
"allocate_stale_primary": {
"index": "index_name",
"shard": 4,
"node": "node1",
"accept_data_loss" : true
}
}
]
}
如果数据不重要,可以不用放到原来的节点上,直接新建一个空分片替代
POST _cluster/reroute
{
"commands": [
{
"allocate_empty_primary": {
"index": "test_11",
"shard": 2,
"node": "node0",
"accept_data_loss" : true
}
}
]
}
- yellow情况下手动分配副本分片操作:
POST /_cluster/reroute
{
"commands" :[
{
"allocate_replica" :
{
"index" : "index_name",
"shard" : 0,
"node": "node1"
}
}
]
}
主分片的恢复用allocate_empty_primary,而副本的恢复用allocate_replica
补充:在unassigned的分片比较多的时候,可以使用脚本
#!/bin/bash
for index in $(curl -s 'http://localhost:9200/_cat/shards' | grep UNASSIGNED | awk '{print $1}' | sort | uniq); do
for shard in $(curl -s 'http://localhost:9200/_cat/shards' | grep UNASSIGNED | grep $index | awk '{print $2}' | sort | uniq); do
echo $index $shard
curl -XPOST 'localhost:9200/_cluster/reroute' -d "{
'commands' : [ {
'allocate' : {
'index' : $index,
'shard' : $shard,
'node' : 'Master',
'allow_primary' : true
}
}
]
}"
sleep 5
done
done
可以参考的几篇文章:
- 总结得最整的是 https://www.datadoghq.com/blog/elasticsearch-unassigned-shards/
- 单独针对主shard出现unassigned的解决可以看http://blog.kiyanpro.com/2016/03/06/elasticsearch/reroute-unassigned-shards/
https://t37.net/how-to-fix-your-elasticsearch-cluster-stuck-in-initializing-shards-mode.html
http://www.wklken.me/posts/2015/05/23/elasticsearch-issues.html - 单独针对副本shard出现unassigned的解决可以看
https://z0z0.me/recovering-unassigned-shards-on-elasticsearch/
https://dpatil1410.wordpress.com/2016/09/24/its-red-how-do-i-recover-unassigned-elasticsearch-shards/