来自:架构之美

ZooKeeper作为分布式应用系统协调服务,在分布式系统中的应用非常广泛,在某些业务场景下甚至可以作为注册中心、分布式锁来使用。ZooKeeper之所以能有如此广泛的应用,与它良好的数据一致性保障机制是分不开的。我们都知道ZooKeeper专门设计了Zab(Zookeeper Atomic Broadcast)协议作为其数据一致性协议。

利用Zab协议的数据写入由Leader结点协调,使用两阶段提交的方式,达到数据的最终一致性。为什么是最终一致性呢?我们先了解下两阶段的过程,如图一所示:

图一

数据写入过程如下:

第一阶段:每次的数据写入事件作为提案广播给所有Follower结点;可以写入的结点返回确认信息ACK;

第二阶段:Leader收到一半以上的ACK信息后确认写入可以生效,向所有结点广播COMMIT将提案生效。

根据写入过程的两阶段的描述,我们知道ZooKeeper保证的是最终一致性,即Leader向客户端返回写入成功后,可能有部分Follower还没有写入最新的数据,所以是最终一致性。

我们都知道ZooKeeper保证的最终一致性也叫顺序一致性,即每个结点的数据都是严格按事务的发起顺序生效的。

ZooKeeper是如何保证事务顺序的呢?

这里需要了解下它的事务ID(ZXID),之前的文章介绍过ZooKeeper的在选举时通过比较各结点的ZXID和机器ID选出新的注结点的。ZXID由Leader节点生成,有新写入事件时,Leader生成新ZXID并随提案一起广播,每个结点本地都保存了当前最近一次事务的ZXID,ZXID是递增的,所以谁的ZXID越大,就表示谁的数据是最新的。

ZXID的生成规则如下图所示:

图二

ZXID有两部分组成:

任期:完成本次选举后,直到下次选举前,由同一Leader负责协调写入;

事务计数器:单调递增,每生效一次写入,计数器加一。

可以看到,ZXID的低32位是计数器,所以同一任期内,ZXID是连续的,每个结点又都保存着自身最新生效的ZXID,通过对比新提案的ZXID与自身最新ZXID是否相差“1”,来保证事务严格按照顺序生效的。

我们都知道ZooKeeper集群的写入是由Leader结点协调的,真实场景下写入会有一定的并发量,那Zab协议的两阶段提交是如何保证事务严格按顺序生效的呢?在本章介绍两阶段提交的部分描述了Leader在收到半数以上ACK后会将提案生效并广播给所有Follower结点。

Leader为了保证提案按ZXID顺序生效,使用了一个ConcurrentHashMap,记录所有未提交的提案,命名为outstandingProposals,key为ZXID,Value为提案的信息。对outstandingProposals的访问逻辑如下:

1、每发起一个提案,会将提案的ZXID和内容放到outstandingProposals中,作为待提交的提案;

2、收到Follower的ACK信息后,根据ACK中的ZXID从outstandingProposals中找到对应的提案,对ACK计数;

3、执行tryToCommit尝试将提案提交,判断流程如下:

3.1:判断当前ZXID之前是否还有未提交提案,如果有,当前提案暂时不能提交;

3.2:判断提案是否收到半数以上ACK,如果达到半数则可以提交;

3.3:如果可以提交,将当前ZXID从outstandingProposals中清除并向Followers广播提交当前提案;

Leader是如何判断当前ZXID之前是否还有未提交提案的呢?由于前提是保证顺序提交的,所以Leader只需判断outstandingProposals里,当前ZXID的前一个ZXID是否存在,代码如下:

图三

 

所以ZooKeeper是通过两阶段提交保证数据的最终一致性,并且通过严格的按照ZXID的顺序生效提案保证其顺序一致性的。

特别推荐一个分享架构+算法的优质内容,还没关注的小伙伴,可以长按关注一下:


长按订阅更多精彩▼如有收获,点个在看,诚挚感谢

聊一聊ZooKeeper的顺序一致性相关推荐

  1. 什么是顺序一致性呢?

    在讲顺序一致性之前,咱们思考一个问题,假如说zookeeper是一个最终一致性模型,那么他会发生什么情况 ClientA/B/C假设只串行执行, clientA更新zookeeper上的一个值x.Cl ...

  2. CAP原理,分布式一致性算法,两阶段提交,三阶段提交,Paxos,Raft,zookeeper的选主过程,zab协议,顺序一致性,数据写入流程,节点状态,节点的角色

    我们知道,一般在分布式应用都有CAP准则: C Consistency, 一致性,分布式中的各个节点数据保持一致 A availability 可用性,任何时刻,分布式集群总是能够提供服务 P par ...

  3. 分布式系统 一致性模型的介绍 以及 zookeeper的 “线性一致性“ 讨论

    文章目录 1. 一致性 概览 1.1 分布式系统的 "正确性" 1.2 线性一致性(Linearizability) 1.3 顺序一致性(Sequential consistenc ...

  4. Java之内存模型的基础、重排序、顺序一致性、volatile、锁、final

    为什么80%的码农都做不了架构师?>>>    深入理解Java内存模型(一)--基础 深入理解Java内存模型(二)--重排序 深入理解Java内存模型(三)--顺序一致性 深入理 ...

  5. Java内存模型深度解析:顺序一致性--转

    原文地址:http://www.codeceo.com/article/java-memory-3.html 数据竞争与顺序一致性保证 当程序未正确同步时,就会存在数据竞争.java内存模型规范对数据 ...

  6. Java内存模型深度解析:顺序一致性

    码农网:http://www.codeceo.com/article/java-memory-3.html 数据竞争与顺序一致性保证 当程序未正确同步时,就会存在数据竞争.java内存模型规范对数据竞 ...

  7. Boost:顺序一致性的测试程序

    Boost:顺序一致性的测试程序 实现功能 C++实现代码 实现功能 顺序一致性的测试程序 C++实现代码 #include <boost/atomic.hpp> #include < ...

  8. 为什么程序员需要关心顺序一致性,而不是 Cache 一致性?

    本文所讨论的计算机模型是Shared Memory Multiprocessor,即我们现在常见的共享内存的多核CPU.本文适合的对象是想用C 或者Java进行多线程编程的程序员.本文主要包括对Seq ...

  9. 顺序一致性内存模型与JMM的“顺序一致性”

    顺序一致性内存模型是一个被计算机科学家理想化了的理论参考模型,它为程序员提供了极强的内存可见性保证.顺序一致性内存模型有两大特性. 1)一个线程中的所有操作必须按照程序的顺序来执行. 2)(不管程序是 ...

最新文章

  1. linux 下挂载光盘
  2. c++类的构造函数详解
  3. 在SpringMVC中使用@RequestBody注解处理json时,报出HTTP Status 415的解决方案
  4. matlab对比度锐化,对比度、清晰度与锐化的理解
  5. 控制程序仅执行一次 php,PHP流程控制(1)
  6. Codeforces Round #513 总结
  7. SSM的整合项目(详细)
  8. 抖音小店无货源,出现退货的情况怎么处理?千万别大意
  9. matlab matconvnet
  10. pearson 相关系数可视化
  11. 力扣LCP3机器人大冒险
  12. 计算机设计项目符号和编号,项目符号和编号
  13. gabor filters matlab,matlab实现gabor filter (1)
  14. 第十四节 OSAL工作原理
  15. 活动星投票奋斗青春,使命必达网络评选微信的投票方式线上免费投票
  16. 1.Balls Bins
  17. 深度优先搜索(c++)
  18. # 研究杂感 × Gephi探秘飞升(第三辑)
  19. NLPIR中科院分词系统初始化失败
  20. 数字图像处理-图像基础-复习总结

热门文章

  1. 关于报错Incorrect username or password ( access token ) Authentication failed for ‘https://gitee.com
  2. 第1关:利用栈实现整数的十进制转八进制
  3. HDU3037(卢卡斯定理)
  4. python traceback模块_Python中的traceback模块
  5. 什么是php伪静态规则,php设置伪静态规则编写 问题
  6. oracle多个instance,Oracle 数据库EM访问多个Instance
  7. luogu P2613 【模板】有理数取余(费马小定理,乘法逆元)
  8. P5568 [SDOI2008]校门外的区间(离散数学应用+线段树+开闭区间处理)(校门三部曲)难度⭐⭐⭐⭐
  9. 过滤流的主要特点是什么_高效过滤器工艺流程是什么 高效过滤器特点介绍【详解】...
  10. 145.二叉树的后序遍历