首页 » PHP教程 » php散布式选举技巧_分布式技能系列 九 分布式选举

php散布式选举技巧_分布式技能系列 九 分布式选举

访客 2024-11-14 0

扫一扫用手机浏览

文章目录 [+]

分布式选举算法有很多,比如raft算法、zookeeper的ZAB算法、Bully 算法等,当然除了须要通过自己实现算法本身之外,也可以借助其他组件来轻松地实现分布式选举(比如zookeeper)。

raft选举

php散布式选举技巧_分布式技能系列  九 分布式选举

raft选举属于“多数派”的民主投票选举办法,即得票数超过一半的节点才可以晋升为leader。
详细选举过程在这里就不做多阐述了,前面已经为此特意写过一篇:分布式技能系列 | 七. raft之leader选举

php散布式选举技巧_分布式技能系列  九 分布式选举
(图片来自网络侵删)

ZAB算法

ZAB(ZooKeeper Atomic Broadcast)也叫原子广播,是zk用来实现分布式折衷功能而设计的。
ZAB同样属于“多数派”的民主投票选举办法。
利用ZAB算法选举时,节点有4种状态:

Observing 状态,即不雅观察者状态,表示当前节点为 Observer,持不雅观望态度,没有投票权和选举权。
如果节点的数据掉队主节点太多,或者做事器负载太大,则在刚进入选举阶段节点就会进入Observing状态,不参与选举过程。
Looking 状态,即选举状态,节点会参与选主过程,拥有投票权和选举权。
Leading 状态,即领导者状态,表示已经选出主,且当前节点为 Leader。
Following状态,即追随者状态,表示对 Leader 的追随,无条件地吸收并处理来自leader的要求。

在ZAB选举过程中,每个节点都会把自己的投票信息广播给其他的所有节点,节点的投票信息包括(epoch,serverId, zxID, voteID),个中前三个表示自身节点的信息:serverId表示做事器id,这个是在节点刚加入集群时,自动天生的做事器id;zxID则表示节点数据的最大id,即数据的最大索引值;epoch则表示当前选举的轮数,每发生一次leader选举,epoch就会加1。
而末了一个voteID则表示当选举节点的serverId。

投票的核心规则是先比较数据id(zxID),如果相等则再比较做事器id(serverId),然后大者胜出。
假设有3个节点参与选举,选举过程如下:

1. 不管是集群刚启动还是leader宕机触发的选举,节点刚开始都是处于Leading状态的。

2.节点从leading状态切换成Looking状态,先将票投给自己,然后将投票信息广播出去。

先将票投给自己

3. 当节点收到来自其他节点的广播信息后,会先将对方的投票信息保存起来,然后再比较自己当前的保举人(即voteId)和广播者谁更适宜当选,如果广播者更适宜,则须要重新修正voteID的值。
比如节点B收到来节点C广播的投票信息后,先比较zxId,创造相同,都是5,然后再比较serverId,节点c胜出,然后节点B重新修正自己的投票,将votedId的值从1改为2。

节点B收到来自节点C的广播信息后,并重新进行了投票

4. ZAB中规定,一旦某个节点的保举人发生了变革,就须要将投票信息重新广播给其他所有节点来担保节点之间投票信息的同等性。
在节点B将自己的保举人改为节点C之后,须要将投票信息重新广播给其他节点,其他节点收到之后则须要更新之前保存过的节点B的投票信息。

终极,节点C获取到大多数的投票

5. 当某个节点根据本地保存的投票箱打算得出自己已经得到了大多数节点的票选,则晋升为leader,然后向其他节点发送“我已经是leader了,你们可以放弃了”的rpc,然后其他节点自动切换成following状态,自此选举结束。

总结一下,ZAB算法紧张是通过广播自己的投票信息到每一个节点,然后收到广播信息的节点再根据信息内容和自己的voteID做比较,来判断是否要变更当前的保举人,一旦保举人发生变更就须要重新广播,来担保节点间投票信息的同等性。

Bully算法

bully算法逻辑就大略多了,投票的规则便是在所有活着的节点中,选取 ID 最大的节点作为主节点。
选举过程:

follower节点A创造leader节点心跳断开,触发leader选举节点A会先判断自己的ID是否为当前活着的节点中ID最大的,如果是,则直接向其他节点发送 Victory ,宣告自己成为leader;否则,向比自己ID大的所有节点发送 Election ,并等待其他节点的回答若在给定的韶光范围内,本节点没有收到来自其他节点回答的 Alive ,则认为自己成为主节点,并向其他节点发送 Victory ,宣誓自己成为主节点;若吸收到来自比自己 ID 大的节点的 Alive ,则等待其他节点发送 Victory 若本节点收到比自己 ID 小的节点发送的 Election ,则回答一个 Alive ,奉告其“我比你大,你没门”。
然后重复2到4的步骤,直到最大的节点宣誓主权。

bully算法逻辑大略、易于实现同时保举速率快,但是选举之后的leader数据可能并不是最全、最新的,这样就造成了数据丢失。

总结一下,bully算法方向于让id最大的节点当选leader,而Raft和ZAB都是属于民主投票的办法,得到超过半数票选的节点才能当选leader,他们之间的差异紧张是在于:

信息通报内容不同:raft的每个节点发送的是“你是否给我投票”,而ZAB的节点则发送的是自己的保举信息,包括自己的信息(数据id、serverId)和保举人,这样做是为了让其他节点都知道自己投了谁。
raft规定每个节点只能有一次投票机会,投过了就不能再投了,而ZAB的节点每收到一次来自其他节点广播的投票信息都会重新比较当前的保举人和广播者,如果广播者更适宜当选,则会重新进行投票,把保举人改为广播者,然后将投票信息重新广播给其他节点

当然,在你开拓一个分布式系统的时候,也可以借助其他组件来轻松地实现分布式选举。
比如我们可以借助zk,利用zk的watch机制,我们可以让每个节点加入集群后都订阅zk上面相同的一个目录,一旦目录下面为空,zk就会关照订阅者们过来抢注leader了,然后率先到达的,会在目录下面新建一个名为“leader”的目录,并当选为leader,然后其他节点创造目录下面已经存在“leader”的目录了,则就此作罢,连续监听,等待下一次机会。

标签:

相关文章