问题描述
我的 Elasticsearch 集群目前处于黄色状态,我该如何排查并解决此问题?
问题分析
黄色集群状态意味着所有索引的主分片已经分配成功,但是至少有一个索引的副本分片未分配成功。最常见的一种场景是我们有一个三节点的集群,同时我们设置了副本数为三,此时集群会出现黄色状态,因为在Elasticsearch 中,主分片和副本分片不能同时存在于一个节点上。示例如下:
PUT mytest
{
"settings":{
"number_of_shards":3,
"number_of_replicas":3
}
}
查看集群状态:
GET /_cluster/health/
返回如下:
{
"cluster_name" : "n15y80awld8i526m",
"status" : "yellow", -->集群状态为黄色
"timed_out" : false,
"number_of_nodes" : 3,
"number_of_data_nodes" : 3,
"active_primary_shards" : 5,
"active_shards" : 14,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 3,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 82.35294117647058
}
除此之外,导致集群变黄还有如下可能原因:
- 磁盘空间不足:只有在节点具有足够的磁盘空间时,群集才能分发副本分片。
- 资源瓶颈,如 JVM 内存压力大。
- 超出分配分区重试的最大次数。
- 集群故障。
- 一些创建,增加副本等操作,可能会导致集群短暂处于黄色状态。
解决方案
在上面的示例中,mytest 这个索引由于副本数设置不合理,导致集群处于黄色状态,下面是一些排查的步骤,供您参考:
1.使用如下命令查看节点状态:
GET /_cluster/health/
2.列出未分配的分区
GET _cat/shards?h=index,shard,prirep,state,unassigned.reason&v
命令输出如下:
index shard prirep state unassigned.reason
mytest 1 p STARTED
mytest 1 r STARTED
mytest 1 r STARTED
mytest 1 r UNASSIGNED INDEX_CREATED
mytest 2 r STARTED
mytest 2 p STARTED
mytest 2 r STARTED
mytest 2 r UNASSIGNED INDEX_CREATED
mytest 0 r STARTED
mytest 0 r STARTED
mytest 0 p STARTED
mytest 0 r UNASSIGNED INDEX_CREATED
3.查看未分配的具体解释
GET _cluster/allocation/explain?pretty
有如下输出:
{
"index" : "mytest",
"shard" : 2,
"primary" : false,
"current_state" : "unassigned",
"unassigned_info" : {
"reason" : "INDEX_CREATED",
"at" : "2022-02-11T05:30:10.312Z",
"last_allocation_status" : "no_attempt"
},
"can_allocate" : "no",
"allocate_explanation" : "cannot allocate because allocation is not permitted to any of the nodes",
"node_allocation_decisions" : [
{
"node_id" : "IeH5e7jjT5WzwH7iTm1xJQ",
"node_name" : "es-master-n15y80awld8i526m-1",
"transport_address" : "172.22.187.74:9300",
"node_attributes" : {
"data_node" : "hot"
},
"node_decision" : "no",
"weight_ranking" : 1,
"deciders" : [
{
"decider" : "same_shard",
"decision" : "NO",
"explanation" : "a copy of this shard is already allocated to this node [[mytest][2], node[IeH5e7jjT5WzwH7iTm1xJQ], [R], s[STARTED], a[id=-63rmbOZQKO-7uvc0Mxs5g]]"
}
]
}
……
……
根据这些信息,我们可以找到对应的处理方法,在这个案例中,通过修改副本分片的个数,或者是增加一个节点解决此问题:
PUT mytest/_settings
{
"number_of_replicas": 2
}
再次查看集群状态,发现已经变为绿色:
GET /_cluster/health/
{
"cluster_name" : "n15y80awld8i526m",
"status" : "green",
"timed_out" : false,
"number_of_nodes" : 3,
"number_of_data_nodes" : 3,
"active_primary_shards" : 5,
"active_shards" : 14,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 100.0
}
针对我们上面提到的其他可能原因,我们还可以从以下方面进行排查:
4. 排查磁盘空间不足导致分配失败
查看磁盘占用情况
GET _cat/allocation?h=shards, disk.indices,disk.used,disk.avail,disk.total,disk.percent&v
输出如下:
shards disk.used disk.avail disk.total disk.percent
5 76.6mb 97.8gb 97.9gb 0
5 76.6mb 97.8gb 97.9gb 0
4 76.3mb 97.8gb 97.9gb 0
对于由于磁盘空间不足导致分片无法分配的问题,有如下解决方案:
- 对数据进行一次整理,删除不需要的索引,及时清理历史数据。
- 纵向扩展存储大小。
- 增加数据节点。
5. 排查由于高 JVM 内存压力 导致分配失败
每个分区分配都需要使用一定的 CPU、堆空间以及磁盘和网络资源。持续高 JVM 内存压力可能会导致分区分配失败。如果是由于此原因,请先降低集群压力,同时考虑如下方法来使集群恢复到绿色运行状态:
- 调整重试次数( index.allocation.max_retries)。
- 先将副本数设置为0,然后再开启分片分配。
- 手动重试未分配的分区。
6. 节点故障导致分配失败
如果所有索引都有副本分区,则单节点故障可能会导致集群暂时进入黄色运行状态。当节点恢复之后,集群将自动变为正常运行状态。节点故障可能由于多种原因造成,如有需要,请联系技术支持。 如果您有其他问题,欢迎您联系火山引擎技术支持服务