腊月27日凌晨的一个紧急 Elasticsearch 线上问题复盘
1、线上问题背景
1.1 某外企集群环境
- 1、10 TB 左右(细节没有说特别具体)集群数据;
- 2、2 节点集群,资源使用率如下图;
- 3、最大索引 600GB
- 4、Elasticsearch 版本:7.17.4
- 5、集群共200分片。
1.2 核心问题
- 症状:集群重启无法启动,已启动了20个小时+,集群仍然无法完全恢复正常状态。
经交流反馈:之前,最长时间 8 小时启动集群。现在临近过年放假,直接无法启动。
1.3 核心报错
Caused by: org.elasticsearch.action.UnavailableShardsException: [.monitoring-kibana-7-2023.01.17][0] primary shard is not active Timeout: [1m], request: [BulkShardRequest [[.monitoring-kibana-7-2023.01.17][0]] containing [2] requests]
... 11 more
[2023-01-17T06:19:46,326][WARN ][o.e.x.m.e.l.LocalExporter] [datanodeprod5.synnex.org] unexpected error while indexi
2、企业技术负责团队提出的方案
- (1)Delete (cancel) the shards?——删除分片
- (2)Move the shards to another node?——移动分片到其他节点
- (3)Allocate the shards to the node?——重新分配分片
- (4)Update 'number_of_replicas' to 2?——更新副本数
Something else entirely?
3、交流排查发现问题
大前提:企业技术团队提出的方案都是基于 Setting 等的修改,但是当前集群一直处于主分片分配的状态,集群一直 red,很多操作是无法执行的。
我们采取一遍交流一遍排查问题,交流发现如下问题:
- 第一:集群规划不合理,数据量10TB+,单只仅2个节点,节点角色都是默认值。
- 第二:极大规模的单索引、极大规模的单分片有好几个,举例:存在超大 600GB 索引。
- 第三:开发&运维都不清楚设置了几个分片和副本(非常诡异,没有重视)。
- 第四:遇到重启耗时8 个小时,没有排查原因,没有引起重视,直到春节放假出了严重问题才足够重视。
一句话概括描述问题所在:
- 由于集群前期规划不合理(分片、副本个数设置不合理,分片大小规划不合理等)导致集群重启耗时巨长(无法正常启动或者说启动一直显示:recovery 30%左右,非常慢!),重启期间(recovery)由于持续有主分片未分配或恢复成功,导致集群一致处于red状态。
- Kibana、Head 插件都无法连接成功(注:集群 red状态,Kibana无法连接 Elasticsearch),只能通过 postman 工具执行有限的少数几个命令,集群响应巨慢甚至很多时候无响应。
4、解决方案探讨
基于如下五种情况,Elasticsearch 自动执行恢复(recovery):
- 1、节点启动(这种类型的恢复称为本地存储恢复);
- 2、将主分片复制到副本分片;
- 3、将分片迁移到同一集群中的不同节点;
- 4、恢复快照(又称作:快照还原 restore 操作);
- 5、Clone, shrink, or split操作。
https://www.elastic.co/guide/en/elasticsearch/reference/current/cat-recovery.html
在集群尚可用的情况下,如下 4.0—4.3 是可以尝试使用的。
4.0 用好 recovery api
GET _cat/recovery?v=true&h=i,s,t,ty,st,shost,thost,f,fp,b,bp&s=index:desc
- 用途:返回有关分片恢复的信息,包括正在进行的和已完成的。
- 注意:分片恢复完成后,恢复的分片可用于搜索和索引。
4.1 确定每个节点将被恢复的并发分片数。
如下设置若生效,本质上是:node_concurrent_incoming_recoveries 和 node_concurrent_outgoing_recoveries 同时生效。
incoming_recoverie 可以简单理解为副本分片的恢复,outgoing_recoveries 可以简单理解为主分片的恢复。
PUT _cluster/settings
{
"transient": {
"cluster.routing.allocation.node_concurrent_recoveries": 3
}
}
默认值是2,理论上调大会增大并发。
https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-cluster.html
4.2 延时分片分配策略
当节点出于任何原因(人为原因或系统异常)离开集群时,主节点会做出以下反应(如下称为步骤 X 是方便后续的解读):
- 步骤1:将副本分片提升为主分片以替换节点上的任何主分片。
- 步骤2:分配副本分片以替换丢失的副本(在有足够的节点的前提下)。
- 步骤3:在其余节点之间均匀地重新平衡分片。
如上操作的好处是:避免集群数据丢失,确保集群高可用。
但可能带来的副作用也非常明显:其一,会给集群带来额外的负载(分片分配非常耗费系统资源);其二,若离开集群的节点很快返回,上述机制的必要性就有待商榷。
此时,延迟分片分配就显得非常必要,设置如下:
PUT _all/_settings
{
"settings": {
"index.unassigned.node_left.delayed_timeout": "6m"
}
}
延时分片分配策略的本质(大白话):当节点离开集群并确认几分钟(自己设定)可以快速上线的情况下,离开的过程中只触发步骤1的将离开节点上的对应的副本分片提升为主分片。此时集群至少不是 red 状态,而是yellow状态。步骤2、步骤3不会发生,此时集群是可用的,待设定的几分钟内下线集群确保重新上线后,分片再重新转为副本分片,此时集群恢复绿色状态。
这个过程有效避免了步骤2、步骤3的分片分配,整体上以最短的时间确保了集群的高可用性。
https://www.elastic.co/guide/en/elasticsearch/reference/current/delayed-allocation.html
4.3 限制恢复速度以避免集群过载
Elasticsearch 限制分配给恢复的速度以避免集群过载。
可以更新此设置以使恢复更快或更慢,具体取决于业务要求。在资源允许的情况下,想快就调大;反之,则相反。
但一味的追求快速恢复,将如下设置过高,正在进行的恢复操作会消耗过多的带宽和其他资源,这可能会破坏集群的稳定性。
PUT _cluster/settings
{
"transient": {
"indices.recovery.max_bytes_per_sec": "100mb"
}
}
注意事项:
- 这是集群层面的动态设置,一旦设置后,对集群中每个节点都生效。
- 如果仅想限制有限的某个节点,可以通过更新 elasticsearch.yml 配置文件的静态配置来实现。
https://www.elastic.co/guide/en/elasticsearch/reference/current/recovery.html
但是,上述操作对于当前出问题的集群都无法实现,主要原因:集群无法响应。
怎么办?这时候需要再寻它法。
能否物理删除不必要的索引,提高集群启动速度呢?这个大胆的想法就这么出来了。试试看!
5、索引恢复提速方案探讨
提速的核心:删除历史“包袱”(将来不再需要的大索引),以间接使得集群恢复加速。
免责说明:
- 如下的验证,仅在单节点集群验证 ok,多节点原理一致。
- 涉及文件的操作,是无法之法,万不得已,不要直接操作文件。
5.1 步骤1:找到待删除大索引的 uuid。
部分命令可执行,可以 cat/index
GET _cat/indices?v&s=docs.count:desc
见下图:
对应 uuid:"znUfwfE3Rt22GMMqANMbQQ"
这一步目的:找到需要删除、业务层面彻底放弃的索引直接物理删除文件,为重启集群会减少恢复压力。
5.2 步骤2:在Elasticsearch 存储路径下找到对应存储。
[root@VM-0-14-centos data]# find ./ -name "znUfwfE3Rt22GMMqANMbQQ"
找到位置:
./indices/znUfwfE3Rt22GMMqANMbQQ
建议:先备份,后执行物理删除。
5.3 步骤3:再次重启集群。
这样理论上可以正常启动,我自己小范围集群验证没有问题。
中间环节的验证截图:
再次强调:这是无法之法!万不得已,不要直接操作文件!!
6、小结
由于涉及线上环境和10TB+的业务数据,开发团队暂没有立即采取文件删除的方案,待团队重新讨论和进一步核实后定夺。
这给我们后来人或者球友的警示如下:
- 第一:“亡羊补牢”,在丢一只羊的时候就得补!!
- 第二:团队里得有个对ES 相对比较熟悉的人,否则遇到难题非常麻烦(尤其节假日期间更为麻烦)。
- 第三:定时快照功能很重要。
- 第四:集群128GB 部署一个节点的必要性待验证。
- 第五:相关调优参数的乱上,就是病急乱投医。要一个个验证可行后才可以大胆用。
- 第六:要有小范围可测试的集群,线上环境动可能就是大问题。
- 第七:大分片(数百GB)有百害而无一例,尤其集群重启、故障恢复就是累赘。大了不怕,ILM 必须得用起来。历史数据该清理的清理、该冷的冷处理方为王道!
文章转载自公众号: 铭毅天下Elasticsearch