腊月27日凌晨的一个紧急 Elasticsearch 线上问题复盘

love374
发布于 2023-5-19 17:17
浏览
0收藏

1、线上问题背景

1.1 某外企集群环境

  • 1、10 TB 左右(细节没有说特别具体)集群数据;

腊月27日凌晨的一个紧急 Elasticsearch 线上问题复盘-鸿蒙开发者社区

  • 2、2 节点集群,资源使用率如下图;

腊月27日凌晨的一个紧急 Elasticsearch 线上问题复盘-鸿蒙开发者社区

  • 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

腊月27日凌晨的一个紧急 Elasticsearch 线上问题复盘-鸿蒙开发者社区

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

腊月27日凌晨的一个紧急 Elasticsearch 线上问题复盘-鸿蒙开发者社区

  • 用途:返回有关分片恢复的信息,包括正在进行的和已完成的。
  • 注意:分片恢复完成后,恢复的分片可用于搜索和索引。

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

见下图:

腊月27日凌晨的一个紧急 Elasticsearch 线上问题复盘-鸿蒙开发者社区

对应 ​​uuid:"znUfwfE3Rt22GMMqANMbQQ"​

这一步目的:找到需要删除、业务层面彻底放弃的索引直接物理删除文件,为重启集群会减少恢复压力。

5.2 步骤2:在Elasticsearch 存储路径下找到对应存储。

[root@VM-0-14-centos data]# find ./ -name "znUfwfE3Rt22GMMqANMbQQ"

找到位置:

./indices/znUfwfE3Rt22GMMqANMbQQ

腊月27日凌晨的一个紧急 Elasticsearch 线上问题复盘-鸿蒙开发者社区

建议:先备份,后执行物理删除。

5.3 步骤3:再次重启集群。

这样理论上可以正常启动,我自己小范围集群验证没有问题。

中间环节的验证截图:

腊月27日凌晨的一个紧急 Elasticsearch 线上问题复盘-鸿蒙开发者社区

再次强调:这是无法之法!万不得已,不要直接操作文件!!

6、小结

由于涉及线上环境和10TB+的业务数据,开发团队暂没有立即采取文件删除的方案,待团队重新讨论和进一步核实后定夺。

腊月27日凌晨的一个紧急 Elasticsearch 线上问题复盘-鸿蒙开发者社区

这给我们后来人或者球友的警示如下:

  • 第一:“亡羊补牢”,在丢一只羊的时候就得补!!
  • 第二:团队里得有个对ES 相对比较熟悉的人,否则遇到难题非常麻烦(尤其节假日期间更为麻烦)。
  • 第三:定时快照功能很重要。
  • 第四:集群128GB 部署一个节点的必要性待验证。
  • 第五:相关调优参数的乱上,就是病急乱投医。要一个个验证可行后才可以大胆用。
  • 第六:要有小范围可测试的集群,线上环境动可能就是大问题。
  • 第七:大分片(数百GB)有百害而无一例,尤其集群重启、故障恢复就是累赘。大了不怕,​​ILM​​ 必须得用起来。历史数据该清理的清理、该冷的冷处理方为王道!



文章转载自公众号: 铭毅天下Elasticsearch

分类
已于2023-5-19 17:17:32修改
收藏
回复
举报
回复
    相关推荐