在 Elasticsearch 的实战中,悬挂索引是一个既常见又容易引起困扰的概念。
今天,我将分享一次处理集群状态为RED,原因为DANGLING_INDEX_IMPORTED 的实战经验,深入探讨悬挂索引的定义、产生原因、管理方法,以及如何有效处理它们,确保读者能够明白并解决自己面临的问题。
值得一提的是,类似问题恰巧是某企业的面试题。
1、悬挂索引的定义
当 Elasticsearch 集群的某个节点因故障(如宕机)暂时离开集群,而该节点上存有的某些索引分片在集群的其他节点上没有副本时,这些索引分片在节点重新加入集群后会被标记为"悬挂"状态。
简而言之,悬挂索引(dangling index)是存在于节点上、但未被集群元数据所识别的索引分片,这意味着它们不会参与到集群的正常索引操作中。
让我们不仅联想到十多年前学过的一个C语言的知识点:野指针。
野指针(Dangling Pointer)是指向"不可预知"内存区域的指针。具体来说,当指针变量在释放了其所指向的内存后未被设为 NULL,或者是指向了一个已经被回收利用的内存块时,这个指针就变成了野指针。
使用野指针访问或操作内存是危险的,因为它可能会导致不可预知的行为或程序崩溃,类似于悬挂索引在集群中的状态,指向了集群中不存在的元数据。
2、遇到的问题及解决步骤
之前遇到过 Elasticsearch 集群状态为RED,原因是出现了大量UNASSIGNED的分片,具体来说是DANGLING_INDEX_IMPORTED的情况。
2.1 识别问题
首先,我使用如下命令确认集群节点状态,发现确实有一个数据节点丢失。通过重启故障节点,虚拟机恢复,但分片仍然未分配。
GET /_cat/nodes
2.2 深入分析
进一步使用如下命令查看未分配的分片,发现都标记为了 DANGLING_INDEX_IMPORTED。
GET /_cat/shards?h=index,shard,prirep,state,unassigned.reason
返回结果:
index1 0 p UNASSIGNED DANGLING_INDEX_IMPORTED
index2 0 p UNASSIGNED DANGLING_INDEX_IMPORTED
index3 0 p UNASSIGNED DANGLING_INDEX_IMPORTED
上面提到的 DANGLING_INDEX_IMPORTED 就是前文提及的悬垂索引导入标记。
DANGLING_INDEX_IMPORTED 标记表示集群已经尝试恢复这些原本丢失的索引分片,将它们重新集成回集群中。这是一种Elasticsearch集群自我恢复的机制,用于尽可能保留和恢复数据。
然而,这种自动导入悬挂索引的操作可能会带来数据完整性和一致性的风险,因为无法保证这些索引的数据是最新的或完整的。
因此,在Elasticsearch的较新版本(7.9之后版本,不含7.9)中,建议使用专门的悬挂索引API来手动管理和恢复这些索引,以确保数据的安全性和一致性。
2.3 诊断原因
通过如下命令诊断未分配分片的具体原因,发现是因为之前的主分片副本已经在集群中的其他节点上找不到了。
GET /_cluster/allocation/explain?pretty
返回信息类似如下:
{
"index" : "XXXX",
"shard" : 0,
"primary" : true,
"current_state" : "unassigned",
"unassigned_info" : {
"reason" : "DANGLING_INDEX_IMPORTED",
"at" : "2021-05-03T11:58:14.859Z",
"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",
这段信息表明:
XXXX索引的第0个主分片因为被识别为悬挂索引并尝试导入而未被分配。尽管有导入尝试,但因为在集群的任何节点上都找不到这个分片的有效副本,导致这个分片无法被正确分配到任何节点上。
这可能指向了数据丢失或数据一致性问题,需要进一步的手动干预和数据恢复操作。
3、悬挂索引重要的操作和注意事项
3.1. 识别悬挂索引
使用如下命令,可以列出所有的悬挂索引。
GET /_dangling
此命令将返回索引名称、索引UUID、创建时间以及所在节点等信息,如下所示:
{
"dangling_indices": [
{
"index_name": "my-index-000001",
"index_uuid": "zmM4e0JtBkeUjiHD-MihPQ",
"creation_date_millis": 1589414451372,
"node_ids": [
"pL47UN3dAb2d5RCWP6lQ3e"
]
}
]
}
3.2 恢复悬挂索引
通过如下命令恢复指定的悬挂索引。
这一步骤要求明确接受可能的数据丢失,因为 Elasticsearch 无法确定悬挂索引的数据是否是最新的。
POST /_dangling/<index-uuid>?accept_data_loss=true
这里 index-uuid 就是 3.1 小节返回的 index_uuid。
3.3 删除悬挂索引
使用如下API可以通过指定其UUID来删除一个悬挂索引,而UUID可以通过使用列出悬挂索引的API找到。
DELETE /_dangling/<index-uuid>?accept_data_loss=true
这个操作需要在Elasticsearch安全特性启用的情况下拥有管理集群的权限。
简而言之,这个API提供了一种方法,允许管理员在确认数据丢失的风险后,清理集群中未被识别为当前部分的悬挂索引。
3.4 自动化脚本恢复
如果存在大量悬挂索引,可以编写脚本自动化处理恢复操作。
3.5 检查集群状态
完成恢复操作后,需检查集群状态以确保数据的完整性和集群的健康。
4、避免悬挂索引的预防措施
-
确保所有节点正确配置并加入集群。
-
在节点离开集群前,正确移除所有索引。
-
避免手动修改 Elasticsearch 数据路径,以防产生悬挂索引。
-
删除大量索引时需确保所有集群节点均在线,以避免产生悬挂索引。
5、结语
通过对Elasticsearch中悬挂索引问题的深入探讨与解决,我们不仅增强了对集群管理的理解,也学会了如何应对潜在的数据一致性风险。
本次实战经历强调了预防、诊断和恢复悬挂索引的重要策略,提醒我们在集群运维过程中必须保持警惕,采取适当措施以维护集群的健康状态。
正确的集群管理实践和对悬挂索引的有效处理,是确保Elasticsearch集群稳定运行、数据安全的关键。
希望本指南能帮助读者在未来遇到类似问题时,能够更加从容不迫地应对,保障数据的完整性和可用性。