如何解决Elasticsearch集群索引重开后报红问题

后端 潘老师 2个月前 (02-08) 45 ℃ (0) 扫码查看

在Elasticsearch的使用过程中,经常会遇到各种各样的问题。今天就来和大家分享一个我实际遇到的问题及解决过程:某组件往Elasticsearch写入数据时速度突然变慢,数据大量积压。查看集群状态后发现,Elasticsearch集群呈红色,这意味着集群出现了严重问题。经过排查,发现是索引关闭重开导致的。下面我就详细讲讲整个排查和解决问题的经过,希望能给大家一些参考。

集群异常现象及初步推测

当时,有个组件负责向Elasticsearch写入数据,突然就出现了写入速度大幅下降的情况,数据一直积压着,无法及时写入。第一反应就是Elasticsearch集群可能压力过大,毕竟数据写入异常大概率和集群状态有关。于是赶紧去查看Elasticsearch集群的状态,果不其然,集群处于red(红色)状态。这个红色状态可就代表着集群有问题,数据的可用性和完整性可能受到了威胁,必须得尽快解决。

问题排查过程

1)查看集群健康值:最先做的就是查看集群的健康值,结果显示集群健康值为red,还有6个未分配的分片。这6个未分配的分片很可能就是导致集群飘红的关键因素,得顺着这个线索继续查下去。

2)查询索引健康值:接着,在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
    }
}

3)查找异常原因:为了弄清楚这些分片为什么没有分配,又使用了_cluster/allocation/explain命令和GET方法,并且在请求体里设置了前面找到的那个red状态索引,分片数则用第一步集群显示的未分片编号4。

{
  "index": "xxx_data_202502",
  "shard": 4,
  "primary": true
}

得到的响应结果显示,这个分片的current_state(当前状态)是unassigned(未分配),unassigned_info(未分配原因)里的reason(原因)是INDEX_REOPENED(索引重新打开),并且还记录了索引重新打开的时间at以及last_allocation_status(上次分配状态)是no_valid_shard_copy(没有有效的分片副本)。把shard属性换成其他两个未分配分片,得到的结果都差不多。这才想起来,这个索引之前确实是关闭状态,最近才重新打开,看来就是索引重开导致了这些分片分配异常。

{
    "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": [.....// 省略具体节点信息]
}

问题解决措施

既然找到了问题所在,就得想办法解决。经过一番研究,决定使用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 省略其他节点
    ]
}

这里先针对编号为4的分片,在所有集群节点上都尝试进行分配。执行完这一步后,再对编号为5和16的分片重复上述操作。没想到这么一试,集群健康值居然变成green(绿色)了,代表集群恢复正常状态。同时,负责写入数据的组件写入速率也立马恢复正常,后台再也没有打印积压日志了。

关于操作的一些思考

在使用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才能执行这个操作,感觉这有点像“霸王条款”,但为了解决问题,也只能按照要求设置了。

这次遇到的Elasticsearch集群因索引关闭重开导致飘红的问题,总算是顺利解决了。希望通过我的分享,大家以后遇到类似问题时,能快速定位并解决。要是你也有相关的经验或者疑问,欢迎在评论区一起讨论。


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/back/14033.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】