ES是如何实现Master选举的?

你好,我是风一样的树懒,一个工作十多年的后端专家,曾就职京东、阿里等多家互联网头部企业。公众号"吴计可师",已经更新了过百篇高质量的面试相关文章,喜欢的朋友欢迎关注点赞

Elasticsearch Master 选举:代码、原理与流程图解析

Elasticsearch 的 Master 选举是其集群高可用的基石。一个稳定的 Master 节点是集群正常运作的关键,它负责管理集群的元数据(如索引、分片、节点信息等),并确保集群的协调一致。理解 Master 选举机制,尤其是 7.x 版本之后引入的投票配置(Voting Configuration),对于维护和优化 Elasticsearch 集群至关重要。

为什么需要 Master 节点?

想象一个乐队,如果没有一个指挥,大家各吹各的调,那肯定是一团糟。Elasticsearch 集群也是如此。Master 节点就扮演着这个"指挥家"的角色:

  • 集群状态管理: 负责维护并发布集群状态(Cluster State),这是集群所有元数据的唯一真实来源,包括节点信息、索引列表、分片分配、模板设置等。
  • 节点管理: 追踪集群中所有节点的状态,包括节点的加入和离开。
  • 索引和分片管理: 负责索引的创建、删除,以及分片的分配和迁移。

Master 选举的触发场景

Master 选举并非一直都在进行,它只在特定情况下被触发:

  1. 集群首次启动: 当一个全新的 Elasticsearch 集群第一次启动时,所有 Master-eligible 节点会尝试选举出第一个 Master。
  2. 当前 Master 节点故障: 现有 Master 节点因为硬件故障、网络问题、JVM 崩溃或被手动停止而下线时,集群会立即启动新的 Master 选举。
  3. 网络分区(Split Brain)恢复: 当集群因网络问题导致"脑裂"时,各个子集群可能会尝试选举 Master。在网络恢复后,为了合并成一个健康集群,也会触发 Master 选举。
  4. Master 节点主动降级: 某些情况下(例如,Master 节点发现自己不再拥有投票配置的多数票),它会主动放弃 Master 角色,触发新的选举。

核心概念:投票配置(Voting Configuration)与 Master-eligible 节点

在 7.x 版本中,Elasticsearch 摒弃了容易误配置的 minimum_master_nodes,转而使用更智能、更健壮的投票配置(Voting Configuration)

  • Master-eligible 节点: 任何可以被选举为 Master 的节点。在 elasticsearch.yml 中,通过 node.roles 配置:

    yaml 复制代码
    # 一个典型的 Master-eligible 节点配置
    node.roles: [master, data, ingest] # 既是 Master 候选,也存储数据,处理摄入
    # 或者,独立 Master 节点(不存储数据,推荐在大集群中使用)
    # node.roles: [master]

    最佳实践: 为了高可用性,建议集群中至少有 3 个或 5 个 Master-eligible 节点。奇数个节点更有利于形成多数派,避免"脑裂"。

  • 投票配置(Voting Configuration): 这是一个动态维护的 Master-eligible 节点集合。只有投票配置中的节点才有权在 Master 选举中投票。Master 节点会负责管理和更新这个集合,例如当新的 Master-eligible 节点加入或现有节点离开时。

Master 选举流程详解

当一个节点启动或发现当前集群没有 Master 时,它会启动一个 Master 选举过程。这个过程大致可以分为以下几个阶段:


详细步骤解析

  1. 发现阶段(Discovery Phase):

    • 目的: 找到集群中的其他节点。

    • 配置: 使用 discovery.seed_hosts 参数来指定一些初始的主机地址,这些地址通常是集群中所有 Master-eligible 节点的 IP 或主机名。

      yaml 复制代码
      # elasticsearch.yml 配置示例
      discovery.seed_hosts: ["192.168.1.10", "192.168.1.11", "192.168.1.12"]

      每个节点会向 seed_hosts 中的地址发送 ping 请求,尝试发现其他 Master-eligible 节点,并交换各自已知的集群状态版本信息。

  2. 收集候选节点并排序:

    • 当一个节点认为自己需要参与 Master 选举时,它会收集所有它能通信到的 Master-eligible 节点列表,作为 Master 候选。
    • 然后,它会根据以下两个主要标准对这些候选节点进行排序(优先级从高到低):
      1. clusterStateVersion 优先级: 拥有最高 clusterStateVersion 的节点优先级最高。 这非常重要,因为 clusterStateVersion 代表了节点所持有的集群元数据的最新程度。选举拥有最新元数据的节点作为 Master,可以最大程度地避免集群状态回滚或丢失最新配置。
      2. 节点 ID 优先级: 如果多个节点的 clusterStateVersion 相同,则节点 ID (Node ID) 字符串排序值最低(字母顺序靠前)的节点优先级更高。 节点 ID 是 Elasticsearch 启动时为每个节点生成的唯一随机字符串。这个规则是为了在所有其他条件都相同的情况下,提供一个确定的、可预测的选举结果,避免无限循环的选举冲突。
  3. 投票与决策:

    • 每个参与选举的节点会向它自己排序出来的"最佳候选节点"发送投票(Vote)
    • 一个节点要想成为 Master,它必须从投票配置中的多数节点 那里获得投票。
      • 示例: 如果集群有 3 个 Master-eligible 节点(A, B, C),并且它们都在投票配置中。那么要成为 Master,至少需要 2 票(即 3/2 + 1 = 2.5,向上取整为 2)。
      • 如果一个节点收到了足够多的投票,它就会宣布自己成为 Master。
  4. 发布集群状态(Publishing Cluster State):

    • 新当选的 Master 节点会立即向集群中的所有其他节点发布最新的集群状态(Cluster State)。这个状态包含了所有最新的集群配置、索引信息和分片分配。
    • 其他节点收到并确认这个新的集群状态后,它们就会承认新的 Master,并更新自己的本地状态,使整个集群达到一致。

防止脑裂(Split Brain):投票配置的威力

"脑裂"是分布式系统中的一个大忌。它发生在网络分区时,一个集群被一分为二,各自选举自己的 Master,导致数据不一致。Elasticsearch 7.x 通过投票配置的多数派原则彻底解决了这个问题。

  • 工作原理: 当 Master 节点发现它不再能够联系到投票配置中的多数节点 时,它会主动降级(step down),放弃 Master 角色。
  • 示例: 假设你有 3 个 Master-eligible 节点(Node1, Node2, Node3)。初始投票配置包含所有这 3 个节点。
    • 场景 1:Node1 是 Master,Node2 宕机。 Node1 仍然能联系到 Node3。在 3 个节点的投票配置中,Node1 和 Node3 仍然组成了 2 个节点的多数派(2 > 3/2=1.5)。Node1 继续保持 Master 身份。
    • 场景 2:Node1 是 Master,Node2 和 Node3 之间网络断开。 导致集群被分隔为两个子集群:{Node1, Node2} 和 {Node3}。
      • Node1 视角: Node1 发现它无法联系到投票配置中的多数(它只能联系到 Node2,而需要联系到 2 个节点才能形成多数)。因此,Node1 会主动降级。
      • Node3 视角: Node3 也发现自己无法联系到投票配置中的多数。
      • 结果是,没有一个子集群能够选举出 Master,从而避免了脑裂。当网络恢复时,节点会重新发现彼此,并启动新的 Master 选举。

首次启动集群的特殊配置:cluster.initial_master_nodes

对于全新的 Elasticsearch 集群,你需要在第一次启动时使用 cluster.initial_master_nodes 参数来"引导"集群。这个参数列出了集群首次启动时希望成为 Master 的 Master-eligible 节点的名称

yaml 复制代码
# elasticsearch.yml 配置示例 - 仅用于首次启动全新集群
# Node1 的 elasticsearch.yml
cluster.name: my-es-cluster
node.name: node-1
node.roles: [master, data]
discovery.seed_hosts: ["192.168.1.10", "192.168.1.11", "192.168.1.12"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"] # 列出所有 Master-eligible 节点的名称

# Node2 的 elasticsearch.yml
cluster.name: my-es-cluster
node.name: node-2
node.roles: [master, data]
discovery.seed_hosts: ["192.168.1.10", "192.168.1.11", "192.168.1.12"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]

# Node3 的 elasticsearch.yml
cluster.name: my-es-cluster
node.name: node-3
node.roles: [master, data]
discovery.seed_hosts: ["192.168.1.10", "192.168.1.11", "192.168.1.12"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]

重要提示: cluster.initial_master_nodes 只在集群首次启动时有效。 一旦集群成功形成,这个设置就会被忽略,并且不应该在后续的节点重启或扩容时再次设置,否则可能导致问题。

总结与展望

Elasticsearch 的 Master 选举机制通过智能的投票配置多数派原则,有效地解决了分布式系统中的"脑裂"问题,确保了集群的高可用性。理解其背后的原理和配置,对于构建和维护稳定、高性能的 Elasticsearch 集群至关重要。

今天文章就分享到这儿,喜欢的朋友可以关注我的公众号,回复"进群",可进免费技术交流群。博主不定时回复大家的问题。 公众号:吴计可师

相关推荐
二哈喇子!2 小时前
若依【(前后端分离版)SpringBoot+Vue3】
java·spring boot·后端
paopaokaka_luck2 小时前
婚纱摄影管理系统(发送邮箱、腾讯地图API、物流API、webSocket实时聊天、协同过滤算法、Echarts图形化分析)
vue.js·spring boot·后端·websocket·算法·echarts
Brookty5 小时前
Java线程安全与中断机制详解
java·开发语言·后端·学习·java-ee
你的人类朋友6 小时前
❤️‍🔥BFF架构版的hello world
前端·后端·架构
孟婆来包棒棒糖~6 小时前
SpringCloude快速入门
分布式·后端·spring cloud·微服务·wpf
雾林小妖6 小时前
springboot集成deepseek
java·spring boot·后端
知识浅谈7 小时前
基于Dify构建本地化知识库智能体:从0到1的实践指南
后端
网络安全打工人7 小时前
CentOS7 安装 rust 1.82.0
开发语言·后端·rust
梦兮林夕7 小时前
04 gRPC 元数据(Metadata)深入解析
后端·go·grpc
pe7er8 小时前
RESTful API 的规范性和接口安全性如何取舍
前端·后端