ElasticSearch分布式架构(二):集群一致性与共识——从Zen Discovery到Raft共识算法

文章目录

    • [一、共识算法的演进:Zen vs. Coordination](#一、共识算法的演进:Zen vs. Coordination)
      • [1. Zen Discovery (ES < 7.0)](#1. Zen Discovery (ES < 7.0))
      • [2. Cluster Coordination (ES 7.0+)](#2. Cluster Coordination (ES 7.0+))
    • [二、Master 选举流程 (Master Election)](#二、Master 选举流程 (Master Election))
      • [1. 选举时机](#1. 选举时机)
      • [2. 7.x+ 选主逻辑图解](#2. 7.x+ 选主逻辑图解)
    • 三、元数据管理 (Meta Data Management)
    • [四、脑裂问题 (Split Brain) 及其解决方案](#四、脑裂问题 (Split Brain) 及其解决方案)
      • [1. 经典场景](#1. 经典场景)
      • [2. 旧版解决方案 (discovery.zen)](#2. 旧版解决方案 (discovery.zen))
      • [3. 新版解决方案 (Cluster Coordination)](#3. 新版解决方案 (Cluster Coordination))
    • 总结

Elasticsearch(简称 ES)之所以能处理 PB 级数据并提供毫秒级搜索体验,核心在于其强大的分布式架构 。在分布式系统中,最棘手的问题莫过于"共识"(Consensus):即如何让集群中的几十上百个节点对系统的当前状态(Cluster State)达成一致。

本文将带您深入 ES 的底层,解析其从早期的 Zen Discovery 到现代基于 Raft 变种的 Cluster Coordination 的演进之路。

在深入细节之前,让我们通过一张思维导图总览 ES 分布式架构的核心模块:
ES 分布式架构
一致性与共识
Legacy
基于 Bully 算法
最小主节点数配置
7.x+
基于 Raft 变种
TLA+ 形式化验证
动态投票配置
Master 选举
选举触发时机
选主流程
元数据管理
Cluster State
2PC
脑裂问题
成因: 网络分区
旧版方案: minimum_master_nodes
新版方案: Voting Quorum


一、共识算法的演进:Zen vs. Coordination

Elasticsearch 的版本分水岭在于 7.0。在此之前和之后,其集群协调层的实现逻辑截然不同。

1. Zen Discovery (ES < 7.0)

在早期版本中,ES 使用自研的 Zen Discovery 模块。

  • 核心逻辑 :基于改进版的 Bully 算法
  • 特点
    • 节点通过 Ping 发现彼此。
    • 通常选择 Node ID 最小且拥有最新集群状态的节点作为 Master。
    • 缺点:虽然简单,但在复杂的网络分区、节点快速重启等边缘场景下,容易出现"反复选主"或"数据不一致"的情况。它属于"Best Effort"(尽力而为)的一致性模型。

2. Cluster Coordination (ES 7.0+)

从 7.0 开始,ES 引入了全新的 Cluster Coordination 子系统。

  • 核心逻辑 :基于 Raft 共识算法 的变种。
  • 改进点
    • 形式化验证:ES 团队使用 TLA+ 模型对算法进行了数学验证,保证了正确性。
    • 安全性:严格保证数据一致性,解决了旧版本中存在的幽灵节点和数据回滚风险。
    • 动态性:不同于标准 Raft 的静态成员列表,ES 允许集群动态伸缩(Dynamic Membership),无需重启集群即可更改投票节点。
特性 Zen Discovery (旧版) Cluster Coordination (新版)
算法基础 Bully 算法变种 Raft 算法变种
一致性强度 弱 (Best Effort) 强 (Safety Guaranteed)
脑裂防护 手动配置 minimum_master_nodes 自动管理 Voting Configuration
配置复杂度 高,扩容需手动计算参数 低,自动引导

二、Master 选举流程 (Master Election)

在 ES 集群中,Master 节点拥有至高无上的权力:它负责维护全局的 Cluster State(包含索引元数据、分片路由表等)。只有 Master 能修改这些状态。

1. 选举时机

当以下情况发生时,会触发选主:

  1. 集群启动时。
  2. 当前的 Master 节点挂掉或网络不可达。
  3. 当前 Master 主动辞职(Step down)。

2. 7.x+ 选主逻辑图解

新版选主流程引入了 Pre-voting (预投票)和 Voting 阶段,确保只有拥有最新数据的节点才能成为 Master。
发现现有 Master
未发现 Master
版本落后
版本最新
是 ( > N/2)

节点启动/Master丢失
Ping 其他节点
加入现有集群
发起 Pre-voting
对比 Cluster State 版本
等待其他节点发起选举
成为 Candidate
向 Voting 节点请求投票
获得过半数票?
当选 Master
随机超时后重试
发布新的 Cluster State
广播我是 Master


三、元数据管理 (Meta Data Management)

Master 当选后,最重要的任务就是管理元数据(Cluster State)。这包括:

  • Settings: 集群层面的配置。
  • Mappings: 索引的字段定义。
  • Routing Table: 分片在哪些节点上。

更新流程:两阶段提交

为了保证所有节点对元数据认知一致,ES 采用类似 2PC (Two-Phase Commit) 的机制来发布状态。
Data Node 2 Data Node 1 Master Node Data Node 2 Data Node 1 Master Node 状态变更 (如: 新建索引) Phase 1: Publish Phase 2: Commit / Apply 收到过半数 Ack? ->> YES PublishRequest (ClusterState Diff) PublishRequest (ClusterState Diff) Ack (我已收到并暂存) Ack (我已收到并暂存) Apply State Locally CommitRequest (应用状态) CommitRequest (应用状态) Apply State Apply State

关键点 :ES 为了性能,传输的通常是 Diff(增量差异),而不是全量的 Cluster State。但在新节点加入时,会发送全量数据。


四、脑裂问题 (Split Brain) 及其解决方案

脑裂是指由于网络分区(Network Partition),一个集群被割裂成两个或多个部分,每一部分都选出了自己的 Master,导致数据写入不一致,甚至数据覆盖。

1. 经典场景

假设有 5 个节点(A, B, C, D, E),A 是 Master。网络故障导致 A, B 和 C, D, E 无法通信。

  • A, B 认为 C, D, E 挂了,A 继续当 Master。
  • C, D, E 认为 A, B 挂了,它们选出 C 当新 Master。
  • 结果:两个 Master 同时接受写入,数据彻底混乱。

2. 旧版解决方案 (discovery.zen)

依靠"过半机制"硬性配置。
公式minimum_master_nodes = (master_eligible_nodes / 2) + 1

配置示例 (elasticsearch.yml)

yaml 复制代码
# 假设有 3 个主节点资格的节点
discovery.zen.minimum_master_nodes: 2
  • 原理:在上述 5 节点分裂场景中,A, B 只有 2 票,小于 (5/2)+1=3,因此 A 自动降级,无法成为 Master。C, D, E 有 3 票,可以工作。
  • 痛点:每次集群扩缩容,管理员必须记得修改这个配置,否则极易出事故。

3. 新版解决方案 (Cluster Coordination)

7.x 之后,移除了 minimum_master_nodes 配置。ES 内部自行维护一个 Voting Configuration(投票配置表)。

  • 初始引导

    集群首次启动时,需显式指定初始的主节点列表:

    yaml 复制代码
    # 7.x+ 首次启动配置
    cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]
  • 动态维护

    当节点加入或离开集群时,Master 会自动更新 Voting Configuration。

    • 如果节点 A 宕机,Master 可能会将 A 从投票列表中移除(如果配置了自动缩容策略)。
    • 即使发生网络分区,只有拥有"当前生效的 Voting Configuration 中过半数节点"的那一部分集群才能选出 Master。

总结

从 Zen Discovery 到 Cluster Coordination 的转变,标志着 Elasticsearch 从一个"易用的搜索引擎"成熟为一个"严谨的分布式数据库"。

生产环境建议

  1. 版本选择:尽量使用 ES 7.10+ 或 8.x 版本,享受更强的共识安全性。
  2. 节点角色分离 :在大型集群中,设置专用的 master-eligible 节点(通常 3 个),不存数据,只负责集群协调,避免 GC 导致的假死(False Positive)触发误选主。
  3. 监控 :密切关注 cluster_state_queuediscovery 相关的日志,任何选主事件都应引起运维警惕。
相关推荐
深蓝电商API5 小时前
async/await与多进程结合的混合爬虫架构
爬虫·架构
峥嵘life5 小时前
Android EDLA CTS、GTS等各项测试命令汇总
android·学习·elasticsearch
u0104058365 小时前
淘宝返利软件后端架构中的防刷单风控规则引擎设计(Drools 应用)
架构
what丶k6 小时前
微服务稳定性守护者:Sentinel 全面使用指南(从入门到企业级落地)
微服务·架构·sentinel
曹天骄6 小时前
基于 Cloudflare Worker + KV 构建高性能分布式测速调度系统(工程实战)
分布式
invicinble7 小时前
一文了解git
大数据·git·elasticsearch
奋进的芋圆7 小时前
Spring Boot 3 高并发事务与分布式事务企业级完整解决方案
spring boot·分布式
猿小羽7 小时前
领域驱动设计(DDD)在电商系统中的架构落地指南(含中英术语对照与图表)
微服务·架构·ddd·领域驱动设计
会周易的程序员7 小时前
openPLC REST API 参考(英译中)
c++·物联网·架构·软件工程·iot
淡泊if7 小时前
Kafka部署模式详解:从单机到分布式集群的核心选择
分布式·kafka