elasticsearch中的Discovery模块负责发现集群中的节点,以及选择主节点。在Elasticsearch 7.0以前,内置的实现称为Zen Discovery。Zen Discovery封装了节点发送(ping)、选主等实现过程。
背景
为什么使用主从模式?
ES的典型场景中的另一个简化是集群中没有那么多节点。通常,节点的数量远远小于单个节点能够维护的连接数,并且网络环境不必经常处理节点的加入和离开。
选举算法
Bully算法是Leader选举的基本算法之一。它假定所有节点都有一个唯一的ID,使用该ID对节点进行排序。任何时候的当前Leader都是参与集群的最高ID节点。该算法的优点是易于实现。
但是,当拥有最大ID的节点处于不稳定状态的场景下会有问题。例如,Master负载过重而假死,集群拥有第二大ID的节点被选为新主,这时原来的Master恢复,再次被选为新主,然后又假死…。ES通过推迟选举,直到当前的Master失效来解决上述问题,只要当前主节点不挂掉,就不重新选主。
但是容易产生脑裂(双主),为此,再通过“法定得票人数过半”解决脑裂问题。
7.X之后的ES,采用一种新的选主算法,实际上是Raft的实现,但并非严格按照Raft论文实现,而是做了一些调整。
什么时候触发选主?
主要在以下三个场景会触发选主:
- 集群启动初始化;
- 集群的Master崩溃的时候;
- 任何一个节点发现当前集群中的Master节点没有得到
n/2 + 1
节点认可的时候。
不执行失效检测可能会产生脑裂(双主或多主),因此需要启动两种失效探测器:
- 在Master节点,启动NodesFaultDetection,简称NodesFD。定期探测加入集群的节点是否活跃。检查一下当前集群总节点数是否达到法定节点数(过半),如果不足,则会放弃Master身份,重新加入集群。
- 在非Master节点启动MasterFaultDetection,简称MasterFD。定期探测Master节点是否活跃。探测Master离线的处理很简单,重新加入集群。本质上就是该节点重新执行一遍选主的流程。
NodesFaultDetection和MasterFaultDetection都是通过定期(默认为1秒)发送的ping请求探测节点是否正常的,当失败达到一定次数(默认为3次),或者收到来自底层连接模块的节点离线通知时,开始处理节点离开事件。
选主过程
ZenDiscovery选主的整体流程可以概括为ÿ