Elasticsearch是如何实现master选举的?什么是脑裂及如何避免脑裂

  1. Elasticsearch是如何实现master选举的

master选举默认是由zendiscovery模块负责。
系统刚刚启动的时候,选取id最小的备选master为master节点。
系统运行起来之后,master和非master节点间是存在一个类似心跳检测的ping机制的,当master ping不到其他节点,或者其他节点ping不到master的时候,他们之间就会互相判断,是否大多数都连不到主节点上了,如果大多数都连不上,那么就开始重新进行master选举。
    master选举的底层实现是对于所有的master备选节点的clustersate进行比较,选择最新的clusterstate节点作为主节点,如果有两个节点的clusterstate值相同,那么选择id较小也就是较早的node作为主节点。我猜测这样选举的原因是用最新clusterstate可以保证集群处在最近的版本中,避免陈旧数据或操作的出现导致数据冲突,而用最早id其实也就是应用最先生成的节点的原因,应该是为了保证集群的稳定,最小的id应该最早执行完所有的数据一致性及各种操作了,所以可以保证数据的相对稳定。这样选举出来的一个主节点如果被大多数的备选主节点同意选为主节点并且该节点也选择自己作为主节点,那么这个节点就可当选,否则进行下一轮选举,一直到选举成功。
     这里有两个重要的配置,elasticsearch.yml文件中的
    discovery.zen.ping.unicast.hosts[]:这是一个master备选节点的主机表,所有想要加入集群的节点都向他们发送请求来加入集群。
    discovery.zen.mininum_master_nodes的数量最好设定为备选主节点数量/2+1.因为这个配置控制了选举的最少节点数,即最少这么多个节点投票通过才能选举出master,否则不行,这样,可以保证一个集群中只有一个主节点。

  • 什么是脑裂,Elasticsearch是如何避免脑裂现象的

脑裂现象就是一个集群因为网络超时或其他原因产生了两个或两个以上以上的主节点的情况,可以理解为一个大集群分裂成了多个小集群,这些小集群各自有各自的master,各自为政,能够自己对数据进行操作,导致大集群产生了数据不一致的现象。
为了避免脑裂,es采取了一个大多数原则的解决方案:即选举主节点时需要得到大多数的支持才可成功选举,需要配置文件中的discovery.zen.mininum_master_node的值为所有master备选主节点的数量/2+1保证大多数的有参选资格的主节点都承认某一节点的master身份才可以,这样就保证了另一部分分裂出去的有参选资格的节点永远也达不到n/2+1的数量,就保证了不会脑裂。
但是其实es的开发者还是忽略了一个问题,就是如果每一个有选举资格的节点如果直投一票,那么肯定可以避免脑裂,但是其实有些情况下,有选举资格的节点时有机会透两票的,比如有三备选个节点的集群ABC,应该选a为master,开始选举 b先投了a,然后a也投了自己,符合大多数原则,按理应该a返回消息,告诉大家我当选,结束选举,但是b投票后,网络通讯变慢b迟迟没收到a的回复导致超时,b又投了c一票,此时c也与a断开,也投了自己,c又当选,这时又出现了脑裂……相当于b投了两票。但是其实这种情况es也做了处理,就是将将集群状态变更分为两个阶段:提交和执行分开,不立即执行新操作。就是在当一个节点选为master,需要先发布一个clasterstate给各个节点,这个东西相当于一个版本号,告诉各个节点我当皇帝了 要按我的规矩来,节点收到之后,会先返回一个信息说收到了,但是不会立即执行,当大多数的节点都返回了成功接收的消息,节点才会真正执行新的clasterstate更新。所以当上面这种情况出现脑裂,虽然在master分发新消息的时候可以被节点接收,但是commit的时候还是会发现不一致,不符合条件的master会自动放弃master状态并重新加入集群。
还有一种解决方案:就是可以将数据和主节点分离,还有当只有两个节点时:设置其中一个为主节点,nodedata为false,另一个nodedata为true,master为false 

 

 

--所有原创内容,可以转载,但请标明出处谢谢

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章