背景
某组件向 ElasticSearch 写入数据,从最近某一天开始写入速度变慢,数据一直有积压。推测是 ElasticSearch 集群压力导致的,查看 ElasticSearch 集群状态,发现集群确实处于 red 状态。
本文记录 ElasticSearch 集群因索引关闭重新打开导致飘红问题排查过程,虽然面向百度开发,蒙着把问题解决了,照例还是要整理一下加深印象的。
具体步骤:
- 查看集群健康值
- 查看索引健康值
- 查看分配解释
- 重新分配
检查集群状态
查看集群状态,集群健康值 red,有 6个未分配的分片:
查询索引健康值
在 Elastic Header 中,使用 _cluster/health?pretty&level=indices
GET 命令查看集群中索引状态。在响应结果中找到了 red 状态的索引,它的 unassigned_shards
属性刚好是 6 。
{
"xxx_data_202502": {
"status": "red",
"number_of_shards": 24,
"number_of_replicas": 1,
"active_primary_shards": 21,
"active_shards": 42,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 6
}
}
查找异常原因
再使用 _cluster/allocation/explain
命令 、GET 方法,请求体设置该索引,分片数用第一步集群显示的未分片编号 4:
{
"index": "xxx_data_202502",
"shard": 4,
"primary": true
}
响应结果:
{
"index": "xxx_data_202502",
"shard": 4,
"primary": true,
"current_state": "unassigned",
"unassigned_info": {
"reason": "INDEX_REOPENED",
"at": "2025-02-05T05:14:38.153Z",
"last_allocation_status": "no_valid_shard_copy"
},
"can_allocate": "no_valid_shard_copy",
"allocate_explanation": "cannot allocate because a previous copy of the primary shard existed but can no longer be found on the nodes in the cluster",
"node_allocation_decisions": [.....// 省略具体节点信息]
}
把 shard
属性换成其他两个未分配分片,结果都一样。
未分配分片的原因是索引重新打开,想起该索引之前确实是关闭状态,最近才打开的。
重分配主分片
使用 reroute
命对这三个未分配分片重新使用 allocate_empty_primary
进行分配。
ElasticSearch Header 里面输入命令 /_cluster/reroute
,方法 POST
,请求体为:
{
"commands": [
{
"allocate_empty_primary": {
"index": "xxx_data_202502",
"shard": 4,
"node": "node-1",
"accept_data_loss": true
}
},
{
"allocate_empty_primary": {
"index": "xxx_data_202502",
"shard": 4,
"node": "node-2",
"accept_data_loss": true
}
}, ....// TODO 省略其他节点
]
}
此处先对 shard 编号为 4,所有集群节点都拼一遍,执行完成后,再对其他 5 和 16编号的分片执行上述操作后,集群健康值竟然变成 green 了,如此顺利,不可思议!ElasticSearch 写入组件的写入速率立即上来了,后台再没有打印积压日志了。
启示录
对于 reroute
命令,不敢贸然执行,想着把 accept_data_loss
属性设置为 false
来执行的,结果响应提示 allocate an empty primary for [xxx][4] can result in data loss, Please confirm by setting the accept_data_loss true
,就是说这个属性是个霸王条款了,只有为 true
才能执行了。
参考:
- 《es: unassigned no_valid_shard_copy》
- 《Elasticsearch 集群健康值 red 分片未分配问题排查方法》