1. 选举时间

  一个 Elasticsearch 集群由多个节点(Node)组成。Elasticsearch 集群正常运行时只能有 1 个 Master 产生,多于 1 个就会发生脑裂,那么这个 Master 是怎么被选举出来的呢,这个后面再说,先说说 Elasticsearch 集群在什么时候会选举 Master:

  • 集群启动初始化;
  • 集群的 Master 崩溃的时候;
  • 任何一个节点发现当前集群中的 Master 节点没有得到n/2+1节点认可的时候,触发选举;

2. 选举算法

  Discovery 模块负责发现集群中的节点、选择主节点。
  Elasticsearch 支持多种不同 Discovery 类型选择,内置的实现有两种:ZenDiscoveryCoordinator
  7.x 以上版本 Coordinator 提供了安全的亚秒级的 Master 选举时间,而 ZenDiscovery 可能要花几秒钟来选择一个新的 Master。
  涉及的核心配置如下,更多参数配置请看官网:https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-discovery-settings.html#master-election-settings

  • discovery.seed_hosts:提供群集中符合 master-eligible(Master 候选节点)的节点地址列表;
  • cluster.initial_master_nodes:设置全新集群中符合主节点条件的初始节点集。默认情况下,此列表为空,这意味着该节点希望加入已经 bootstrap 的集群;

  Elasticsearch 集群中可能会有多个 master-eligible node,在集群启动时需要进行 Master 选举,保证只有一个当选 Master。如果有多个 node 当选为 Master,则集群会出现脑裂,脑裂会破坏数据的一致性,导致集群行为不可控,产生各种非预期的影响。

2.1 Coordinator

  Elasticsearch 7.x 重构了一个新的集群协调层 Coordinator,采用 Raft 的实现,但并非严格按照 Raft 论文实现,而是根据 Elasticsearch 做了一些调整。

2.2 ZenDiscovery

  Bully 算法是 Leader 选举的基本算法之一,优点是易于实现,该算法和 Solr Leader Shard 选举非常相似。
  该算法假定所有节点都有一个唯一的 ID,使用该 ID 对节点进行排序,选择最小的节点作为 Master。
  任何时候当前 Leader 都是参与集群的最小 ID 节点。该算法的优点是易于实现。
  但是当拥有最小 ID 的节点处于不稳定状态的场景下会有问题。  例如 Master 负载过重而假死,集群拥有第二小 ID 的节点被选为新主,这时原来的 Master 恢复,再次被选为新主,然后又假死。
  Elasticsearch 通过推迟选举,直到当前的 Master 失效来解决上述问题,只要当前主节点不挂掉,就不重新选主。但是容易产生脑裂(双主),为此,再通过 “法定得票人数过半” 解决脑裂问题。

3. 选举流程

  从源码分析,选举集群状态版本最高的作为 Master。
  先根据节点的 clusterStateVersion 比较,clusterStateVersion 越大,优先级越高。clusterStateVersion 相同时,进入 compareNodes,其内部按照节点的 ID 比较(ID 为节点第一次启动时随机生成)。
  选举集群状态版本最高的作为 Master 的原因如下:

  • 为了保证新 Master 拥有最新的 clusterState(即集群的 meta),避免已经 commit 的 meta 变更丢失。因为 Master 当选后,就会以这个版本的 clusterState 为基础进行更新;
  • 当 clusterStateVersion 相同时,节点的 ID 越小,优先级越高。即总是倾向于选择 ID 小的 Node,这个 ID 是节点第一次启动时生成的一个随机字符串。之所以这么设计,应该是为了让选举结果尽可能稳定,不要出现都想当 Master 而选不出来的情况;

  具体流程:

  • Elasticsearch Master 的选取是 ZenDiscovery 模块负责的,主要包含 Ping(节点之间通过这个 RPC 来发现彼此)和 Unicast(单播模块包含一个主机列表以控制哪些节点需要 ping 通)这两部分;
  • ping 所有节点,并获取 PingResponse 返回结果(代码详见 ZenDiscovery 的 findMaster() 方法);
  • 对所有可以成为 Master 的节点(node.master: true)根据 nodeId 字典排序,每次选举每个节点都把自己所知道节点排一次序,然后选出第一个(第 0 位)节点,暂且认为它是 Master 节点;
  • 如果对某个节点的投票数达到一定的值(可以成为 Master 节点数 n/2+1)并且该节点自己也选举自己,那这个节点就是 Master,否则重新选举一直到满足上述条件;
  • Master 节点的职责主要包括集群、节点和索引的管理,不负责文档级别的管理;data 节点可以关闭 http 功能。

参考文献

  【1】https://blog.csdn.net/penriver/article/details/118940313?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164671887916780265437233%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164671887916780265437233&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-2-118940313.pc_search_result_cache&utm_term=Elasticsearch+Master%E9%80%89%E4%B8%BE%E6%B5%81%E7%A8%8B&spm=1018.2226.3001.4187
  【2】https://zhuanlan.zhihu.com/p/110079342
  【3】https://zhuanlan.zhihu.com/p/110015509
  【4】https://blog.csdn.net/thomas0yang/article/details/56496409?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164672103216780271939766%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=164672103216780271939766&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-3-56496409.pc_search_result_control_group&utm_term=Elasticsearch+Discovery&spm=1018.2226.3001.4187
  【5】https://blog.csdn.net/qq_35373760/article/details/108974308