Elasticsearch 集群脑裂常见场景故障排除
Elasticsearch 是一款强大的分布式搜索和分析引擎,它依赖于稳定的网络和正确的配置来维护集群的完整性。“脑裂”场景发生在集群被划分为多个独立的节点组,每个组都认为自己是主节点时。这会导致数据不一致、节点无响应,并可能导致数据丢失。了解其原因并知道如何诊断和解决这些问题,对于维护健康的 Elasticsearch 环境至关重要。
本文将引导您了解 Elasticsearch 脑裂场景的常见原因,重点关注与网络相关的问题和法定人数(quorum)配置错误。我们将提供实用的步骤,包括诊断检查和配置调整,以帮助您恢复集群的稳定性并防止未来再次发生。
理解脑裂
当节点之间的通信,特别是主节点(master-eligible nodes)之间的通信中断时,就会出现脑裂情况。在 Elasticsearch 这样的分布式系统中,节点会选举一个主节点来管理集群范围的操作。如果主节点变得无法访问,或者网络分区将节点分组隔离,每个隔离组可能会选举出新的主节点。这会产生冲突的集群状态,因为每个“主节点”都独立运行,从而导致可怕的脑裂。
脑裂的关键后果包括:
- 数据不一致: 索引可能在一个分区中被更新,而在另一个分区中未更新。
- 节点无响应: 节点可能无法加入集群或有效通信。
- 写入失败: 需要集群范围协调的操作将失败。
- 潜在数据丢失: 如果分区持续存在且未正确合并,数据可能会丢失。
常见原因和诊断步骤
脑裂问题通常源于网络不稳定或集群设置不正确。以下是最常见的原因以及如何诊断它们:
1. 网络分区
网络问题是脑裂最常见的原因。这可能包括一般网络连接问题、防火墙配置错误或路由问题,这些问题会将节点或整个可用区隔离。
诊断步骤:
- Ping 和 Traceroute: 从每个节点尝试 ping 和 traceroute 到集群中的所有其他节点。注意丢包、高延迟或无法访问的主机。
bash # 在 Linux/macOS 系统上的示例 ping <other_node_ip> traceroute <other_node_ip> - 检查防火墙规则: 确保 Elasticsearch 的传输端口(默认
9300)在所有节点之间是开放的。防火墙可能是间歇性连接问题的常见来源。 - 验证网络基础设施: 检查路由器、交换机和负载均衡器是否存在任何配置错误或故障迹象。
- 云提供商特定设置: 如果在云环境(AWS、GCP、Azure)中运行,请检查安全组、网络访问控制列表 (NACL) 和虚拟私有云 (VPC) 路由表是否存在限制。
- 分析 Elasticsearch 日志: 查找提及
[connection_exception]、[netty]、[remote_transport]或[master_not_discovered]错误的日志。这些通常表明与网络相关的通信失败。
2. 主节点(Master-Eligible Node)故障
当主节点(master-eligible nodes)发生故障或变得不可用时,集群会尝试选举新的主节点。如果网络分区阻止节点相互可见,可能会同时发生多次主节点选举,从而导致脑裂。
诊断步骤:
- 监控主节点: 使用
_cat/masterAPI 查看当前哪个节点被选举为主节点。
bash GET _cat/master?v - 检查节点状态:
_cat/nodesAPI 提供集群中所有节点及其角色的概览。
bash GET _cat/nodes?v - 分析集群健康状况:
_cluster/healthAPI 显示集群的整体健康状况。黄色或红色状态通常表示分片分配出现问题,这可能与脑裂有关。
bash GET _cluster/health
3. 不正确的法定人数(Quorum)配置 (discovery.zen.minimum_master_nodes)
此设置对于防止脑裂至关重要。它定义了集群要选举主节点并运行所需的最小主节点(master-eligible nodes)数量。如果此值设置得太低,少数节点仍然可以形成法定人数并选举出主节点,即使它们与集群的其余部分隔离。
最佳实践: 将 discovery.zen.minimum_master_nodes 设置为 (N / 2) + 1,其中 N 是集群中主节点(master-eligible nodes)的数量。这可确保在选举主节点时必须有大多数主节点可用。
配置示例(在 elasticsearch.yml 中):
如果您有 3 个主节点(master-eligible nodes):
discovery.zen.minimum_master_nodes: 2 # (3 / 2) + 1 = 2
如果您有 5 个主节点(master-eligible nodes):
discovery.zen.minimum_master_nodes: 3 # (5 / 2) + 1 = 3
Elasticsearch 7.x 及更高版本的注意事项:
在 Elasticsearch 7.0 及以上版本中,discovery.zen.minimum_master_nodes 已被弃用,取而代之的是 cluster.initial_master_nodes。对于 Elasticsearch 7.x,如果您正在进行升级,您可能仍然会遇到与旧设置相关的问题。在 Elasticsearch 8.x 及更高版本中,集群会根据引导期间的初始主节点配置自动处理此问题。引导集群的新推荐方法是使用 cluster.initial_master_nodes。
# 对于 Elasticsearch 7.x,在初始集群引导期间使用
cluster.initial_master_nodes: [ "node-1", "node-2", "node-3" ]
诊断步骤:
- 检查
elasticsearch.yml: 检查所有节点上的discovery.zen.minimum_master_nodes或cluster.initial_master_nodes设置。 - 验证一致性: 确保此设置在所有主节点(master-eligible nodes)之间是一致的。
- 重新计算: 如果您最近添加或删除了主节点(master-eligible nodes),请确保正确重新计算并更新此值。
解决脑裂情况
解决脑裂情况需要谨慎的步骤来确保数据完整性。一般方法是识别分区,停止除一个分区之外的所有节点,然后允许集群重新加入。
警告: 这些步骤涉及停止 Elasticsearch 节点并可能重新启动它们。在尝试恢复之前,请务必进行最近的备份。
步骤 1: 识别分区
使用网络诊断工具和 _cat/nodes API(如果可访问)来确定集群是如何分区的。您可能需要访问各个节点的日志来查看哪些节点可以相互通信。
步骤 2: 选择一个存活分区
决定您希望哪个分区成为权威分区。这通常是包含脑裂前活动的主节点的那个分区,或者是数据最新的那个分区。标记要保持运行的分区中的节点。
步骤 3: 停止非存活分区中的所有节点
关闭您不要保留的分区中的所有 Elasticsearch 进程。
步骤 4: 重置并重启存活分区
在存活分区中的节点上:
- 停止 Elasticsearch: 确保所有 Elasticsearch 进程已停止。
- 清除事务日志(可选但推荐): 为确保数据一致性,您可以清除存活节点上的事务日志。这是一个更激进的步骤,应谨慎操作。
- 找到
elasticsearch数据目录。 - 为每个索引找到并删除
dev/shm/elasticsearch/nodes/<node_id>/indices/<index_name>/0/translog目录。 - 警告: 这会强制从主分片重新索引。如果存活分区中的主分片损坏或丢失,这可能导致数据丢失。如果可能,让集群重新同步通常更安全。
- 找到
- 确保
minimum_master_nodes正确: 仔细检查discovery.zen.minimum_master_nodes(或新版本的cluster.initial_master_nodes)是否已为计划在集群中拥有的主节点(master-eligible nodes)的最终数量正确配置。 - 启动 Elasticsearch: 在存活分区中的节点上启动 Elasticsearch 服务。它们应该能够选举出主节点并形成一个稳定的集群。
步骤 5: 恢复其他节点
在存活分区稳定后:
- 启动 Elasticsearch: 在之前属于非存活分区中的节点上启动 Elasticsearch 服务。它们应该会尝试加入现有集群。Elasticsearch 将从现在稳定的集群中的主分片同步数据。
- 监控集群健康状况: 使用
_cat/nodes和_cluster/health确保所有节点重新加入,并且集群状态恢复为绿色。
预防策略
- 强大的网络监控: 对您的网络基础设施实施全面的监控,密切关注 Elasticsearch 节点之间的延迟和丢包。
- 冗余的主节点(Master-Eligible Nodes): 始终拥有奇数个主节点(至少 3 个),以便进行基于多数的法定人数。
- 正确的
minimum_master_nodes: 这是您的主要防线。确保它始终设置为(N / 2) + 1,其中N是主节点(master-eligible nodes)的数量。 - 隔离主节点(Master-Eligible Nodes): 考虑将特定的节点指定为主节点,并将其与数据节点分开,以减少负载和潜在的干扰。
- 预演和测试: 在将集群配置更改(尤其是网络相关的更改)应用于生产环境之前,在预演环境中进行彻底测试。
- 定期备份: 对您的 Elasticsearch 数据进行定期、自动的备份。这是您的最终安全网。
结论
Elasticsearch 中的脑裂场景可能具有挑战性,但通过勤奋的配置和监控,通常是可以预防的。通过了解根本原因、进行彻底的网络检查以及正确配置法定人数设置,您可以大大降低遇到这些问题的风险。万一发生脑裂,遵循结构化的恢复过程将有助于恢复集群的完整性并确保数据一致性。通过强大的网络和正确的集群设置来优先考虑预防,是维护稳定可靠的 Elasticsearch 部署的关键。