阅读 170

Zookeeper 强一致性的保证

ZooKeeper 使用了一种叫 ZAB(ZooKeeper Atomic Broadcast,ZooKeeper 原子消息广播协议)的算法协议进行广播和选举。ZAB协议具体分为2个部分:

消息广播阶段

image.png

读请求由收到请求的节点自己处理,写数据的机制是客户端把写请求发送到leader节点上(如果发送的是follower节点,follower节点会把写请求转发到leader节点),leader节点会把数据通过proposal请求发送到所有节点(包括自己),所有到节点接受到数据以后都会写到自己到本地磁盘上面,写好了以后会发送一个ack请求给leader,leader只要接受到过半的节点发送ack响应回来,就会发送commit消息给各个节点,各个节点就会把消息放入到内存中(放内存是为了保证高性能),该数据就会用户可见了。

崩溃恢复阶段

下面的几种情况都会进入崩溃恢复阶段:

  • 初始化集群,刚刚启动的时候

  • Leader 崩溃,因为故障宕机

  • Leader 失去了半数的机器支持,与集群中超过一半的节点断连。

崩溃阶段还包括数据同步操作,同步集群中最新的数据,保证集群数据的一致性。

具体流程:
1.Leader崩溃后,各个节点状态变更为Looking

2.各个Server节点都会发出一个投票,参与选举

3.集群接收来自各个服务器的投票,开始出了投票和选举。出了投票过程对比的是Zxid,谁的Zxid大谁就是Leader。如果Zxid一样,谁的Server id(就是zoo.cfg中的myid)大,随时Leader。此外投票过程只要有节点收到了半数票数后,就是新的Leader。

4.选出新Leader后,Leader会发送一个同步请求,所有Follower同步新Leader的数据

如何保证数据一致性

leader执行commit了,还没来得及给follower发送commit的时候,leader宕机了,这个时候如何保证数据一致性?

当leader宕机以后,ZooKeeper会选举出来新的leader,新的leader启动以后要到磁盘上面去检查是否存在没有commit的消息,如果存在,就继续检查看其他follower有没有对这条消息进行了commit,如果有过半节点对这条消息进行了ack,但是没有commit,那么新对leader要完成commit的操作。

客户端把消息写到leader了,但是leader还没发送proposal消息给其他节点,这个时候leader宕机了,leader宕机后恢复的时候此消息又该如何处理?

客户端把消息写到leader了,但是leader还没发送portal消息给其他节点,这个时候leader宕机了,这个时候对于用户来说,这条消息是写失败的。假设过了一段时间以后leader节点又恢复了,不过这个时候角色就变为了follower了,它在检查自己磁盘的时候会发现自己有一条消息没有进行commit,此时就会检测消息的编号,消息是有编号的,由高32位和低32位组成,高32位是用来体现是否发生过leader切换的,低32位就是展示消息的顺序的。这个时候当前的节点就会根据高32位知道目前leader已经切换过了,所以就把当前的消息删除,然后从新的leader同步数据,这样保证了数据一致性。

同一个客户端,先发出写请求,leader将写请求事务广播给follow,如果半数follow成功,但是发出请求的follow没有成功,按照半数即成功的原理,leader会返回写操作成功,此时该客户端再读取数据,导致读取到的是旧的值,不符合同一个session写后读的保证

zookeeper不保证读一致性,是弱一致性,如果要保证读到的数据是最新的,读取之前要使用sync方法 但是 zookeeper 的读写一致不是在 server 做的,而是 server & client 配合的;client 会记录它见过的最大的 zxid (在你的场景下,就是这条写入 的 zkid),读取的时候,如果 server 发现 这条 zxid 比 server 端的最大 zxid 大,则拒绝,client 会自动重连到其他server(还在同一个 session) —— 最终会落到有新数据的 server 上,因为半数已经同意;

zookeeper的优缺点

基于 ZAB 算法,ZooKeeper 集群保证数据更新的一致性,并通过集群方式保证 ZooKeeper 系统高可用。但是 ZooKeeper 系统中所有服务器都存储相同的数据,也就是数据没有分片存储,因此不满足分区耐受性。


作者:爱学习的Chloe
链接:https://juejin.cn/post/7023285737139208206


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐