Zookeeper中有Paxos算法的影子,今天说一下其原因:
1、zk简介:
zookeeper是由雅虎创建,zookeeper并没有直接采用Paxos算法,而是采用了一种被称为ZAB(zookeeper Atomic Broadcast)的一致性协议。
zookeeper是一个典型的分布式数据一致性的解决方案,分布式应用程序可以基于它实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能。
zookeeper基本概念
集群角色 Leader:
Leader服务器为客户端提供读写服务
Follower:Follower为客户端提供读服务
Observer:Observer为客户端提供读服务,不参与选举Leader,不参与事务投票,不影响写性能提高集群的读性能。
会话(Session) Session是指客户端会话,是客户端连接服务端的一个TCP长连接。服务端的Watch事件通知也是通过该TCP连接。
2、ZAB协议原理:
ZAB协议并不像Paxos算法那样,是一种通用的分布式一致性算法,它是一种特别为zookeeper设计的崩溃可恢复的原子消息广播算法。 zookeeper服务器数据状态的事务请求的处理方式: 所有事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器被称为Leader,其他的服务器就是Follower。Leader服务器负责将一个客户端事务请求转换成 一个事务Proposal(提议),并将该Proposal分发给集群中所有的Follower服务器。之后Leader服务器需要等待所有Follower服务器的反馈,一旦超过半数的Follower服务器进行了正确的反馈后,那么Leader就会再次向所有的Follower服务器分发Commit消息,要求其将前一个Proposal进行提交。 ZAB基本模式: 1、崩溃恢复,Leader选举 2、消息广播,事务消息 tips:如果集群中其他机器接收到客户端的事务请求,那么这些非Leader服务器首先将这个事务请求转发给Leader服务器。
3、ZAB协议相关的消息广播:
ZAB协议的消息广播就是原子广播协议,类似于一个二阶段提交,对客户端的请求,Leader会生成一个Proposal,并发送给所有的机器,然后再分别收集各自的选票,最后进行事务提交。
消息广播二阶段提交过程要点:
1)、所有Follower要么正常反馈事务Proposal要么抛弃
2)、Leader只要有过半数的Follower反馈了ack就进行事务提交,不要等待所有Follower都反馈ack
3)、整个消息广播过程是具有FIFO特性的,能够保证消息提议的发送和接收的顺序性
4)、Leader会为事务Proposal分配一个全局单调递增的唯一ID即ZXID
5)、消息广播时,Leader会为每一个Follower分配一个单独队列,讲需要广播的Proposal放入队列
6)、每一个Follower接收到Proposal后,会以事务日志的方式写入到本地磁盘,写入磁盘成功后反馈ack给Leader 7、Leader收到半数ack反馈后,广播一个Commit消息给所有Follower,此时Leader完成事务提交,Follower收到Commit消息后进行事务提交。
4、崩溃恢复应用场景:
崩溃恢复模式开启的条件: Leader出现崩溃或者网络原因导致Leader失去了与过半Follower的联系。 ZAB协议要确保两点:
1)、ZAB协议需要确保那些已经在Leader服务器上提交(commit)的事务最终被所有的服务器提交
2)、ZAB协议需要确保丢弃那些只在Leader上被提出的事务(只是被提出还没有被提交) Leader选举算法: 确保提交已经被Leader提交的事务,丢弃只被提出的事务,如果让Leader选择算法能够保证新选举出来的Leader拥有集群中所有机器最高编号(ZXID最大),那么一定能保证新Leader一定具有所有已经提交的提案。
5、怎么恢复?
数据同步 新Leader会为每一个Follower准备一个队列,并将那些没有被各Follower同步的事务以Proposal消息的形式逐个发送给Follower,并在每一个Proposal消息后面紧接着再发送一个Commit消息,标识该事务已经被提交。等所有Follower都从Leader同步过来后,Leader就会讲该Follower加入到真正可用的Follower列表并开始之后的流程。
ZAB如何处理被丢弃的事务Proposal? ZXID设计,ZXID是一个64位数字,低32位是一个单调递增的计算器,每一个新增的事务请求低32位都会+1. 高32位代表Leader周期epoch编号,每当选举产生一个新的Leader,就会从这个Leader上取出本地日志中最大的事务Proposal的ZXID,并从ZXID解析出对应的epoch值,然后再对其进行加1操作。这个就是新Leader的epoch值。 并将低32位设置为0.
通过zxid的大小直接确定。zxid的编码方式为高32位为epoch(即纪元,可以理解为代),低32位为每个proposal顺序递增的数字。每次变换一个leader,则epoch加一,可以理解为改朝换代了,新朝代的zxid必然比旧朝代的zxid大,新代的leader可以要求将旧朝代的proposal清除。
到此、ZAB协议分享完毕,详细阅读、认真思考定会早日理解。