Zookeeper学习系列【三】Zookeeper 集群架构、读写机制以及一致性原理(ZAB协议)

前言

同窗们,在上一章中,咱们主要讲了Zookeeper两种启动模式以及具体如何搭建。本章内容主要讲的是集群相关的原理内容,第一章能够当作是Zookeeper原理篇的基础部分,本章则是Zookeeper原理篇进阶部分,有关于Zookeeper集群的读写机制、ZAB协议的知识解析。html

本篇的内容主要包含如下几点:数据库

  • Zookeeper 集群架构
  • Zookeeper 读写机制
  • ZAB协议
  • 关于Zookeeper 集群的一些其余讨论
    • Zookeeper(读性能)可伸缩性 和 Observer节点
    • Zookeeper 与 CAP 理论
    • Zookeeper 做为 服务注册中心的局限性

1、Zookeeper 集群架构

接下来咱们来讲一说Zookeeper的集群架构。apache

Zookeeper 集群中的角色

第一章提过,Zookeeper中,能改变ZooKeeper服务器状态的操做称为事务操做。通常包括数据节点建立与删除、数据内容更新和客户端会话建立与失效等操做服务器

  • Leader 领导者 :Leader 节点负责Zookeeper集群内部投票的发起和决议(一次事务操做),更新系统的状态;同时它也能接收而且响应Client端发送的请求。
  • Learner 学习者
    • Follower 跟随者 : Follower 节点用于接收而且响应Client端的请求,若是是事务操做,会将请求转发给Leader节点,发起投票,参与集群的内部投票,
    • Observer 观察者:Observer 节点功能和Follower相同,只是Observer 节点不参与投票过程,只会同步Leader节点的状态。
  • Client 客户端

Zookeeper 经过复制来实现高可用。在上一章提到的集群模式(replicated mode)下,以Leader节点为准,Zookeeper的ZNode树上面的每个修改都会被同步(复制)到其余的Server 节点上面。网络

上面实际上只是一个概念性的简单叙述,在看完下文的读写机制ZAB协议的两种模式以后,你就会对这几种角色有一个更加深入的认识。架构

2、Zookeeper 读写机制

读写流程

下图就是集群模式下一个Zookeeper Server节点提供读写服务的一个流程。分布式

如上图所示,每一个Zookeeper Server节点除了包含一个请求处理器来处理请求之外,都会有一个**内存数据库(ReplicatedDatabase)**用于持久化数据。ReplicatedDatabase 包含了整个Data Tree。微服务

来自于Client的读服务(Read Requst),是直接由对应Server的本地副原本进行服务的。性能

至于来自于Client的写服务(Write Requst),由于Zookeeper要保证每台Server的本地副本是一致的(单一系统映像),须要经过一致性协议(后文提到的ZAB协议)来处理,成功处理的写请求(数据更新)会先序列化到每一个Server节点的本地磁盘(为了再次启动的数据恢复)再保存到内存数据库中。学习

集群模式下,Zookeeper使用简单的同步策略,经过如下三条基本保证来实现数据的一致性

  • 全局串行化全部的写操做

    串行化能够把变量包括对象,转化成连续bytes数据. 你能够将串行化后的变量存在一个文件里或在网络上传输. 而后再反串行化还原为原来的数据。

  • 保证同一客户端的指令被FIFO执行(以及消息通知的FIFO)

FIFO -先入先出

  • 自定义的原子性消息协议

    简单来讲,对数据的写请求,都会被转发到Leader节点来处理,Leader节点会对此次的更新发起投票,而且发送提议消息给集群中的其余节点,当半数以上的Follower节点将本次修改持久化以后,Leader 节点会认为此次写请求处理成功了,提交本次的事务。

乐观锁

Zookeeper 的核心思想就是,提供一个非锁机制的Wait Free 的用于分布式系统同步的核心服务。其核心对于文件、数据的读写服务,并不提供加锁互斥的服务

可是因为Zookeeper的每次更新操做都会更新ZNode的版本(详见第一章),也就是客户端能够本身基于版本的对比,来实现更新数据时的加锁逻辑。例以下图。

就像咱们更新数据库时,会新增一个version字段,经过更新先后的版本对比来实现乐观锁。

3、ZAB协议

终于到了ZAB协议,讲述完ZAB协议,你们对Zookeeper的一些特性会有更深的体会,对本文的其余内容也会有更透彻的理解。

ZAB 协议是为分布式协调服务ZooKeeper专门设计的一种支持崩溃恢复一致性协议,这个机制保证了各个server之间的同步。全称 Zookeeper Atomic Broadcast Protocol - Zookeeper 原子广播协议。

两种模式

Zab协议有两种模式,它们分别是恢复模式广播模式

广播模式

广播模式相似于分布式事务中的 Two-phase commit (两阶段式提交),由于Zookeeper中一次写操做就是被当作一个事务,因此这实际上本质是相同的。

广播模式,一次写请求要经历如下的步骤

  1. ZooKeeper Server接受到Client的写请求
  2. 写请求都被转发给Leader节点
  3. Leader节点先将更新持久化到本地
  4. Leader节点将这次更新提议(propose)给Followers,进入收集选票的流程
  5. Follower节点接收请求,成功将修改持久化到本地,发送一个ACK给Leader
  6. Leader接收到半数以上的ACK时,Leader将广播commit消息并在本地deliver该消息。
  7. 当收到Leader发来的commit消息时,Follower也会deliver该消息。

广播协议在全部的通信过程当中使用TCP的FIFO信道,经过使用该信道,使保持有序性变得很是的容易。经过FIFO信道,消息被有序的deliver。只要收到的消息一被处理,其顺序就会被保存下来。

可是这种模式下,若是Leader自身发生了故障,Zookeeper的集群不就提供不了写服务了吗?这就引入了下面的恢复模式。

恢复模式

简单点来讲,当集群中的Leader故障或者服务启动的时候,ZAB就会进入恢复模式,其中包括Leader选举和完成其余Server和Leader之间的状态同步

NOTE:选主是ZAB协议中最为重要和复杂的过程。这里面的概念知识较多,放在本章一块儿讲反而不利于理解本章的知识,因此我打算在下一章单独介绍,同窗们能够选择性地食用。

关于Zookeeper 集群的一些其余讨论

1. Zookeeper(读性能)可伸缩性 和 Observer节点

一个集群的可伸缩性便可以引入更多的集群节点,来提高某种性能。Zookeeper实际上就是提供读服务和写服务。在最先的时候,Zookeeper是经过引入Follower节点来提高读服务的性能。可是根据咱们以前学习过的读写机制和ZAB协议的内容,引入新的Follower节点,会形成Zookeeper 写服务的降低,由于Leader发起的投票是要半数以上的Follower节点响应才会成功,你Follower多了,就增长了协议中投票过程的压力,可能会拖慢整个投票响应的速度。结果就是,Follower节点增长,集群的写操做吞吐会降低

在这种状况下,Zookeeper 在3.3.3版本以后,在集群架构中引入了Observer角色,和Follower惟一的区别的就是不参与投票不参与选主。这样既提高了读性能,又不会影响写性能。

另外提一句,Zookeeper的写性能是不能被扩展的,这也是他不适合当作服务注册发现中心的一个缘由之一,在服务发现和健康监测场景下,随着服务规模的增大,不管是应用频繁发布时的服务注册带来的写请求,仍是刷毫秒级的服务健康状态带来的写请求,都会Zookeeper带来很大的写压力,由于它自己的写性能是没法扩展的。后文引的文章会详细介绍。

2. Zookeeper 与 CAP 理论

分布式领域中存在CAP理论:

  • C:Consistency,一致性,数据一致更新,全部数据变更都是同步的。

  • A:Availability,可用性,系统具备好的响应性能。

  • P:Partition tolerance,分区容错性。以实际效果而言,分区至关于对通讯的时限要求。系统若是不能在时限内达成数据一致性,就意味着发生了分区的状况,必须就当前操做在C和A之间作出选择,也就是说不管任何消息丢失,系统均可用。

CAP 定理的含义 -- 阮一峰

该理论已被证实:任何分布式系统只可同时知足两点,没法三者兼顾。 所以,将精力浪费在思考如何设计能知足三者的完美系统上是愚钝的,应该根据应用场景进行适当取舍。

根据咱们前面学习过的读写机制和ZAB协议的内容,Zookeeper本质应该是一个偏向CP的分布式系统。由于广播协议本质上是牺牲了系统的响应性能的。另外从它的如下几个特色也能够看出。也就是在第一章最后提出的几个特色。

① 顺序一致性 从同一个客户端发起的事务请求,最终将会严格按照其发起顺序被应用到ZooKeeper中。

② 原子性 全部事务请求的结果在集群中全部机器上的应用状况是一致的,也就是说要么整个集群全部集群都成功应用了某一个事务,要么都没有应用,必定不会出现集群中部分机器应用了该事务,而另一部分没有应用的状况。

③ 单一视图 不管客户端链接的是哪一个ZooKeeper服务器,其看到的服务端数据模型都是一致的。

④ 可靠性 一旦服务端成功地应用了一个事务,并完成对客户端的响应,那么该事务所引发的服务端状态变动将会被一直保留下来,除非有另外一个事务又对其进行了变动。

3. Zookeeper 做为 服务注册中心的局限性

直接引一篇阿里中间件的文章吧,讲的比我好。实际在生产状况下,大多数公司没有达到像大公司那样的微服务量级,Zookeeper是彻底能知足服务注册中心的需求的。

阿里巴巴为何不用 ZooKeeper 作服务发现?

总结

本章主要介绍了Zookeeper的集群架构,详述了ZK的几种角色和组件,还介绍了Zookeeper的读写机制和最核心的ZAB协议,最后对其余一些比较杂的知识点统一归在一块儿讨论了一下。

本章的知识我本人认为信息量仍是蛮大的,整理完以后我本身对Zookeeper集群服务的机制原理有了更深的体会。阅读时最好可以结合第一章的一些基础概念,这样更有助于理解,让知识点先后呼应。但愿能对你理解Zookeeper起到帮助。

下一章我会详细介绍本章未介绍的Zookeeper选主过程(Leader Election)。

参考

[1] <zookeeper.apache.org/doc/r3.4.13… 官方文档

[2] 阿里巴巴为何不用 ZooKeeper 作服务发现?

[3] www.cnblogs.com/sunddenly/p…

[4] CAP 定理的含义 -- 阮一峰

相关文章
相关标签/搜索