Paxos算法
Basic Paxos
角色介绍
client,系统外部角色,请求发起者,向民众
Propser,接受Client请求,向集群提出提议(propose),并在发送冲突的时候,起到冲突调节的作用,向议员,替民众提出议案
Acceptor,提议投票和接受者,只有在形成发法定人数(Quorum),提议才会被接受,像国会
leaner,提议接受者,备份,对集群一致性没有说明影响,向记录员
分为两大步骤,每一步骤又分为两小步骤
proposer提出一个提案N,然后向Acceptor的某个超过半数的子集成员发送提案N的prepare请求
基本流程
部分节点失败,但是绝大部分正常
上图在当Acceptor其中有一个节点失败了,但是存活的还是大多数进行了响应,因此后面的流程正常进行
proposer失败
潜在的问题,就是活锁
正如我们最开始的步骤,第二步
2.promise
如果N大于此Acceptor之前接受的任何提案编号则接受,否则拒绝
当在进行第二步操作的时候,此时又来了一个提案编号是2,则Acceptor就会接受提案2,此时前一次的proposer看到自己的提案被替换了,就会在此提一个提案,编号为3,就这样一次类推,最后造成活锁
当然这个问题也很好解决,就是当第二个提案提出的时候,如果已经有提案了,我们可以等一会,这样当过一会第一个提案可能已经选了出来.
可以发现Basic Paxos有很多问题,难实现,效率低,发生活锁因此提出了优化
Multi Paxos
Leader唯一的propser,所有请求都需要经过此leader
这样当下次客户端请求的时候,此时领导还没有改变,就会直接提出I+1提案,提案的内容为w,不会产生冲突,然后进行流程选出提案,这样的好处节省了一次RPC请求,且这种算法也简化了角色。如下图
ZAB协议
所有事务请求必须有一个全局唯一的服务器来协调处理,这样的服务器就是leader,其余的其他服务器则成为Follower的服务器,Leader服务器就是负责一个客户端事务请求转换一个事务proposal,并提交proposal分发给其他follower,但其中大部分follower反馈可以的时候,leader服务器就会在再次向所有的Follower服务器分发commit消息,要求其将前一个proposal进行提交
ZAB要解决两个问题,设计两种模式
消息广播
消息广播类似一个二阶段提交,但是又不一样,是因为移除了中断逻辑,所有follower服务器要么正常反馈leader提出的事务proposal,要么抛弃leader服务器,同时ZAB协议将二阶段提交中的中断逻辑意味着我们不需要等到多有Folloer的反馈.
崩溃恢复
上面我们提到了二阶段的优化,移除了中断阶段,只要大多数follower的反馈,因此出现数据不一致的情况,且当leader服务器崩溃或者网络原因导致失去了过半follower的联系,因此崩溃恢复就起到了作用
基本特性
leader在ZAB协议中是一个重要角色,正如生活中,部门的领导,如果领导离职了,公司肯定会重新选择一个leader组织,其中这个选择一个领导是一个非常重要的过程。如下过程
既然要当领导,每个人都希望自己是领导,因此就会投票选举,且会每个人都会有一个记录表,来记录这个信息,比如有三个人A,B,C
整个选举过程,并且每个人选举,都代表了一个事件,为了保证分布式系统的时间有序性,因此每个事件都分配了一个ZXID,相当一个编号,64位的数字,高32代表了leader周期epoch编号,每当选举产生一个新的leader服务器,就会从这个leader服务器中解析最大事务proposal的ZXID,然后取出高32位的epoch加1,低32为代表一个事务计数器,产生一个事务就会累计1操作。
崩溃恢复基本过程
1.Leader election(选举阶段):节点在一开始都处于选举阶段,只要有一个节点得到超半数节点的票数,它就可以当选准 leader。
2. Discovery(发现阶段):在这个阶段,followers 跟准 leader 进行通信,同步 followers 最近接收的事务提议。
3. Synchronization(同步阶段):同步阶段主要是利用 leader 前一阶段获得的最新提议历史,同步集群中所有的副本。同步完成之后 准 leader 才会成为真正的 leader。
4. Broadcast(广播阶段):到了这个阶段,Zookeeper 集群才能正式对外提供事务服务,并且 leader 可以进行消息广播。同时如果有新的节点加入,还需要对新节点进行同步。
ZAB和Paxos算法区别
相同点
不同点
Leader如何选举
server id(sid),服务id,比如有三台服务器,编号分别是1,2,3
zxid:事务id,服务器存放的数据事务id,值越大说明数据越新
Epoch,投票的次数即第几代领导
server状态,LOOKING,竞选状态,FOLLOWING,随从状态,参与投票,OBSERVING,观察状态,不参与投票,leading,领导者状态
首先要明白几个东西,zookeeper节点是根据什么进行比较选举成leader,首先比较的是事物id即zxid(节点越新zxid就越大),如果zxid一样,就比较sid,即集群节点的唯一标识
什么时候进行选举的
服务器初始化
服务1启动
服务1感觉自己可以当领导,就会投自己一票,不够半数以上,选举无法完成
此时投票结果,服务器1位1票,状态为LOOKING
服务2启动
服务2启动也感觉自己可以,投自己一票,但是和服务1交流得出,服务2的id比较大,因此更改服务1的投票,选择投给了服务2,此时达到了半数,因此此时服务2就变成了leader,同时更改服务1的状态为follower
服务3启动
此时服务1,2,已经不是looking状态了,不会更改投票信息了,且已经有了leader,因此服务4虽然此时投了自己一票,但是和其他服务器交流,然后还是更改了投票给了服务2,然后此时服务3的状态改成了Following
最终服务2成为了leader,其他服务是follower
运行期间leader宕机进行新的leader选举
此时集群leader宕机,
如上图,每个服务器都会先选择自己,然后每个台机器会将自己的投票发给其他机器,如果比自己的zxid大,就会重新投一次,比如server1收到三张偷拍哦,发现server2的zxid为102,因此修改自己的投票,给了server2,最终server2成为了leader.