常用一致性算法
- paxos协议 没有发现实际使用
- zab协议 zookeeper使用
- Bully协议 elasticsearch mongo使用
- raft协议 据说consul使用了,redis哨兵貌似使用了
paxos协议
Zab协议
Zab协议的全称是 Zookeeper Atomic Broadcast (Zookeeper原子广播)
Zab协议原理
Zab协议要求每个Leader都要经历三个阶段
- 选举:要求zookeeper集群必须选举出一个 Leader 进程,同时 Leader 会维护一个 Follower 可用客户端列表。将来客户端可以和这些 Follower节点进行通信
- 同步:Leader 要负责将本身的数据与 Follower 完成同步,做到多副本存储。这样也是提现了CAP中的高可用和分区容错。Follower将队列中未处理完的请求消费完成后,写入本地事务日志中
- 广播:Leader 可以接受客户端新的事务Proposal请求,将新的Proposal请求广播给所有的 Follower
选举
节点在一开始都处于选举节点,只要有一个节点得到超过半数节点的票数,它就可以当选准 Leader,只有到达同步阶段,这个准 Leader 才会成为真正的 Leader。 在zookeeper的最新版本中删除了其他的选举算法,当前仅支持Fast Leader Election。
Fast Leader Election
- 每个Server发出一个投票。 由于是初始情况,所有服务器将自己作为Leader服务器来进行投票
- 接受来自各个服务器的投票。 集群的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票、是否来自LOOKING状态的服务器。
- 处理投票。 针对每一个投票,服务器都需要将别人的投票和自己的投票进行PK
- 优先检查ZXID。ZXID比较大的服务器优先作为Leader。
- 如果ZXID相同,那么就比较myid。myid较大的服务器作为Leader服务器。
- 统计投票。 每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接受到相同的投票信息
- 改变服务器状态。 一旦确定了Leader,每个服务器就会更新自己的状态,如果是Follower,那么就变更为FOLLOWING,如果是Leader,就变更为LEADING。
同步阶段
同步阶段主要是利用 Leader 前一阶段获得的最新 Proposal 历史,同步集群中所有的副本。 只有当 quorum(超过半数的节点) 都同步完成,准 Leader 才会成为真正的 Leader。Follower 只会接收 zxid 比自己 lastZxid 大的 Proposal。
广播阶段
到了这个阶段,Zookeeper 集群才能正式对外提供事务服务,并且 Leader 可以进行消息广播。同时,如果有新的节点加入,还需要对新节点进行同步。
Bully协议
Bully是一种分布是选举算法,中文称为霸道选举算法,改算法的基本目标每次都会选出存活的进程中ID最大的候选者
Bully算法基本假设
- 通信通道是可靠的,更进一步的假设是系统中任何两个进程之间都可以通信
- 进程之间相互知道各自的进程编号,也就是说算法依赖一个全局的数据
- 程序能够明确地判断出一个正常运行的进程和一个已经崩溃的进程
选举流程
- 如果进程是最大的ID,直接向所有人发送Victory消息,成为新的Leader;否则向所有比它大的ID的进程发送Election消息
- 如果进程在发送Election消息后没有收到Alive消息,则进程向所有人发送Victory消息,成为新的Leader
- 如果进程收到了从比自己ID还要大的进程发来的Alive消息,进程停止发送任何消息,等待Victory消息(如果过了一段时间没有等到Victory消息,重新开始选举流程)
- 如果进程收到了比自己ID小的进程发来的Election消息,回复一个Alive消息,然后重新开始选举流程
- 如果进程收到Victory消息,把发送者当做Leader