如下的问题及方案探讨来自:微信交流及腾讯会议。
3、最大索引 600GB
4、Elasticsearch 版本:7.17.4
5、集群共200分片。
经交流反馈:之前,最长时间 8 小时启动集群。现在临近过年放假,直接无法启动。
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 indexing monitoring document
Something else entirely?
大前提:企业技术团队提出的方案都是基于 Setting 等的修改,但是当前集群一直处于主分片分配的状态,集群一直 red,很多操作是无法执行的。
我们采取一遍交流一遍排查问题,交流发现如下问题:
一句话概括描述问题所在:
由于集群前期规划不合理(分片、副本个数设置不合理,分片大小规划不合理等)导致集群重启耗时巨长(无法正常启动或者说启动一直显示:recovery 30%左右,非常慢!),重启期间(recovery)由于持续有主分片未分配或恢复成功,导致集群一致处于 red 状态。
Kibana、Head 插件都无法连接成功(注:集群 red状态,Kibana无法连接 Elasticsearch),只能通过 postman 工具执行有限的少数几个命令,集群响应巨慢甚至很多时候无响应。
基于如下五种情况,Elasticsearch 自动执行恢复(recovery):
https://www.elastic.co/guide/en/elasticsearch/reference/current/cat-recovery.html
在集群尚可用的情况下,如下 4.0—4.3 是可以尝试使用的。
GET _cat/recovery?v=true&h=i,s,t,ty,st,shost,thost,f,fp,b,bp&s=index:desc
用途:返回有关分片恢复的信息,包括正在进行的和已完成的。
注意:分片恢复完成后,恢复的分片可用于搜索和索引。
如下设置若生效,本质上是: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
当节点出于任何原因(人为原因或系统异常)离开集群时,主节点会做出以下反应(如下称为步骤 X 是方便后续的解读):
如上操作的好处是:避免集群数据丢失,确保集群高可用。
但可能带来的副作用也非常明显:其一,会给集群带来额外的负载(分片分配非常耗费系统资源);其二,若离开集群的节点很快返回,上述机制的必要性就有待商榷。
此时,延迟分片分配就显得非常必要,设置如下:
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
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
但是,上述操作对于当前出问题的集群都无法实现,主要原因:集群无法响应。
怎么办?这时候需要再寻它法。
能否物理删除不必要的索引,提高集群启动速度呢?这个大胆的想法就这么出来了。试试看!
提速的核心:删除历史“包袱”(将来不再需要的大索引),以间接使得集群恢复加速。
免责说明:
部分命令可执行,可以 cat/index
GET _cat/indices?v&s=docs.count:desc
见下图:
对应 uuid:"znUfwfE3Rt22GMMqANMbQQ"
这一步目的:找到需要删除、业务层面彻底放弃的索引直接物理删除文件,为重启集群会减少恢复压力。
[root@VM-0-14-centos data]# find ./ -name "znUfwfE3Rt22GMMqANMbQQ"
找到位置:
./indices/znUfwfE3Rt22GMMqANMbQQ
建议:先备份,后执行物理删除。
这样理论上可以正常启动,我自己小范围集群验证没有问题。
中间环节的验证截图:
再次强调:这是无法之法!万不得已,不要直接操作文件!!
由于涉及线上环境和10TB+的业务数据,开发团队暂没有立即采取文件删除的方案,待团队重新讨论和进一步核实后定夺。
这给我们后来人或者球友的警示如下:
——2023-01-18 0:29 初稿,2023-01-30 23:20 重新梳理
更短时间更快习得更多干货!
和全球 1800+ Elastic 爱好者一起精进!