其实网络上关于Zookeeper的文章多如牛毛,起初,我也只是想写个学习笔记,做个记录。但是既然动笔了,我想就不单是做个笔记,而是希望写一些对读者有帮助的内容。
Zookeeper作为一个流行的分布式协调服务,要了解他,我们首先问自己两个问题,Why and How?我们为什么要用Zookeeper?Zookeeper是怎么工作的?
Why(用途)
首先,我们为什么要用到Zookeeper?我们可以把软件系统类比为一个公司,当公司规模小的时候,老板就能决定所有的事情;
但当公司规模发展壮大后,老板一个人管理公司有些吃力,但又不放心把所有权力交给另外一个人,这时老板想了个办法,成立了一个CEO团队,团队采用民主化运作进行集体决策。
ECO团队的主要任务:
- 制定公司各项规章制度并对全公司公布
- 收集各部门的提交的意见,决定是否采纳
- 公司规章制度更新后,通知涉及的部门
类似的,Zookeeper作为分布式协调服务,他主要通过两个手段对外提供服务,即服务目录 + 通知。
- 维护一个类文件系统的数据结构,存储信息,给业务提供服务
- 接收客户端提交的修改请求,并在内部同步达成一致
- 当信息发生变化时,消息推送给感兴趣的监听者
Zookeeper的应用场景包括:数据发布/订阅、命名服务、配置中心、分布式锁、集群管理、选主与服务发现等等。
基本概念
先了解下Zookeeper里的一些基本概念。
目录节点(znode)
Zookeeper类文件系统中的每个节点称为znode,znode里包含了节点的自身信息和业务数据,根据节点属性,可以分为2大类,分别是持久化节点和临时节点,每类下有分为普通节点和按顺序编号节点,分别描述如下:
-
PERSISTENT:持久化目录节点
- 客户端断开后,节点依然存在
-
PERSISTENT_SEQUENTIAL:持久化顺序编号目录节点
- 客户端断开后,节点依然存在
- Zookeeper会给此类节点名称进行顺序编号
-
EPHEMERAL:临时目录节点
- 客户端断开后,节点被删除
-
EPHEMERAL_SEQUENTIAL:临时顺序编号目录节点
- 客户端断开后,节点被删除
- Zookeeper会给此类节点名称进行顺序编号
监听机制(Watcher)
客户端注册监听它关心的节点,当节点发生变化(数据改变、删除、子节点增加/删除)时,监听器会被触发,并将事件信息推送到客户端。
节点角色
Zookeeper本身作为一个分布式服务,有若干节点组成集群对外提供服务,集群节点包括Leader、Follower、Observer 3种角色。
- Leader:领导者,为客户端写服务;维护集群状态。Leader由集群选举产生。
- Follower:跟随者,为客户端提供读服务;定期向Leader汇报自身状态;参与写服务器过半写成功的决策和Leader选举。
- Observer:观察者,为客户端提供读服务;定期向Leader汇报自身状态;不参与决策和选举。Observer可以在不影响写性能的情况下提升集群的读性能。
客户端会话
Zookeeper客户端通过TCP长连接连接到服务集群,会话(Session)从第一次连接开始就已经建立,之后通过心跳检测机制来保持有效的会话状态。客户端通过这个连接发送请求并接收响应,接收到Watch事件的通知。
当由于网络故障或者客户端主动断开等原因,导致连接断开,此时只要在会话超时(Session TimeOut)时间之内重新建立连接,则之前创建的会话依然有效。
ZXID
对于每个事务,Zookeeper都会分配一个全局唯一的事务ID(ZXID)。ZXID由64位组成。其中高32位为纪元号(Epoch:集群每选举一次Leader,纪元号加1);低32为本纪元内的事务序号(事务序号在每个纪元会清零)
民主选举(过半机制)
所谓民主选举,是指当集群中超过一半的节点同意一个事务时,即表示事务执行成功(不包括Observer)。Leader提交一个提案时,只要过半数节点反馈ACK,就任务提案被集群接受了,Leader不需要等待剩余节点反馈ACK,直接广播Commit消息;Leader选举和数据同步时,亦如此。
提案和事务
Zookeeper收到客户端的一个写请求,称为提案(Proposal),把一个提案提交到集群并应用生效的过程,叫事务
How(ZAB协议)
下面我们再来看下,作为一个CEO团队,它是如何运作的。作为一个优秀的管理团队,他的运作要满足CAP原则,即:
- 一致性:团队成员达成一致
- 可用性:不能某人离职了就玩不转了
- 分区容错性:紧急状态下联系不上全部成员的时候要能决策重要事项)
团队通过以下几条规则确保CAP:
- 团队成员人数不能太少,至少要3人及以上
- 由团队成员民主(过半数同意)选举产生一个首席CEO,根据任人唯贤能上能下的宗旨,首席CEO干的不好了,可由团队重新选举产生。
- 公司所有的决策,由首席CEO从各部门收集后产生提案,并由CEO团队民主表决通过。
Zookeeper的工作原理,和以上类似。主要依赖ZAB(ZooKeeper Atomic Broadcast)一种支持崩溃恢复的原子广播协议来完成。
ZAB的特性
-
一致性保证
- 可靠提交(Reliable Delivery):如果一个事务被Leader提交了,那么最终一定会被所有的节点提交
- 全局有序(Total Order):假设A、B两个事务,Leader先提交了A,再提交B,那么可以保证所有节点都以先A后B的顺序提交
- 因果有序(Causal Order):如果发送者在事务A提交后再发送B,那么B必定在A之后执行
- 只要过半节点启动,系统就能正常运行
- 当节点下线后重启,必须保证能恢复到当前正在执行的事务
ZAB协议有两种工作模式,分别是广播模式和恢复模式。
- 恢复模式:集群启动后,先通过恢复模式选出Leader,并完成节点间数据同步;
- 广播模式:恢复完成后,系统进入广播模式,开始接受客户端请求,并确保节点间数据同步。
广播模式(Broadcast)
广播模式主要用来实现集群节点间数据的同步,每个同步操作定义为一个事务,使用两阶段提交协议完成事务提交,以客户端写数据为例进行说明事务操作:
- Leader从客户端接受写请求(如果Follower接受到写请求,会转发给Leader)
- Leader生成一个新提案(Proposal),并为提案分配ZXID,启动提案提交事务
- Leader将提案发送给所有Follower
- Follower将接收到的提案加入历史队列(History Queue),并给Leader回复ACK
- 当Leader收到过半Follower的ACK后,Leader Commit提案,并向Follower广播提案Commit请求
- Follower接收到提案Commit请求后,Commit本地的提案,事务结束
根据全局有序的规则,Follower提交事务时,需要通过历史队列,确认此提案的ZXID是否是最小的,最小才提交,不然就等待其他ZXID更小的事务先提交
恢复模式(Recovery)
当整个集群在启动时,或者Leader失联后,ZAB协议就会进入恢复模式,恢复模式的流程如下:
- 集群通过过民主举机制产生新的Leader,纪元号加1,开始新纪元
- 其他节点从新的Leader同步状态
- 过半节点完成状态同步,退出恢复模式,进入消息广播模式
Leader选举流程
Leader选举是集群正常运行的前提,当集群启动或Leader失联后,就会进入Leader选举流程。
选举期间,集群间通过选票(Vote) 进行进行互相选举,选票主要包含两个信息:
- 节点ID:集群配置文件中预配置的每个节点的ID
- ZXID:节点已经Commit的最大提案的ID
选举流程:
- 所有节点进入LOOKING状态
- 每个节点广播携带自身ID和ZXID的选票,投票推举自己为Leader
- 节点接收其他节点发送的选票,把选票信息和自己推举的选票进行PK(选票中ZXID大者胜出,ZXID相同,则ID大者胜出)
- 如果外部选票获胜,则保存此选票信息,并把选票广播出去(赞成该选票)
- 循环上述3-4步骤
- 当有选票得到超过半数节点赞成,且该选票的所有者也赞成该选票,则选举成功,该选票所有者成为Leader
- Leader切换为LEADING,Follower切换为FOLLOWING,Observer切换为OBSERVING状态,选举结束,进入数据同步流程。
数据同步流程,是要以Leader数据为基础,让集群数据达到一致状态。
数据同步流程
- 新Leader把本地快照加载到内存,并通过日志应用快照之后的所有事务,确保Leader数据库是最新的
- Follower和Observer把自身的ZXID和Leader的ZXID进行比较,确定每个节点的同步策略
- 根据同步策略,Leader把数据同步到各节点
- 每个节点同步结束后,Leader向节点发送NEWLEADER指令
- 同步完成的节点返回ACK
- 当Leader收到过半节点反馈的ACK时,认为同步完成
- Leader向节点发送UPTODATE指令,通知集群同步完成,开始对外服务
遗留问题
根据ZAB协议,Leader已经Commit的事务,重新选主后,要能在新集群生效。但是有一种情况,对于一个提案Px,原Leader向集群广播提案并收到了过半Follower的ACK,此时Leader会自身先执行Commit再向集群广播Commit,但还未来得及向集群广播Commit消息,Leader就挂了。
此后通过选举,原Follower成为了新Leader,新Leader中Px肯定是未Commit的,系统如何保证Px生效呢?这个还没看研究源码,有知道请告知下!!
参考材料