栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

初识Zookeeper(一)—基本概念|ZAB协议|ZXID——《从Paxos到Zookeeper分布式一致性原理》读书笔记

初识Zookeeper(一)—基本概念|ZAB协议|ZXID——《从Paxos到Zookeeper分布式一致性原理》读书笔记

第三章 Zookeeper与Paxos

文章目录
  • 第三章 Zookeeper与Paxos
    • 3.1 初识Zookeeper
      • 3.1.1 Zookeeper 核心功能
      • 3.1.2 Zookeeper 设计目标
        • 目标一:简单的数据模型
        • 目标二:可以构建集群
        • 目标三:顺序访问
        • 目标四:高性能
      • 3.1.3 Zookeeper 基本概念
        • 集群角色
        • 会话(Session)
        • 数据节点(ZNode)
        • 版本
        • Watcher
        • ACL(Access Control Lists)
      • 3.2 Zookeeper的ZAB协议
        • 3.2.1 ZAB协议
        • 3.2.2 ZAB协议两种模式
          • 消息广播
          • 崩溃恢复
        • ZAB是如何处理那些需要被丢弃的事务Proposal的?

Apache Zookeeper 为分布式应用提供了 高效且可靠的分布式协调服务,提供了诸如 统一命名服务、配置管理和分布式锁等分布式的基础服务。

在解决分布式数据一致性方面,Zookeeper并没有直接采用Paxos算法,而是采用了一种被称为 ZAB (Zookeeper Atomic Brodcast) 的一致性协议。

3.1 初识Zookeeper 3.1.1 Zookeeper 核心功能

Zookeeper 是一个典型的分布式数据一致性的解决方案,分布式应用程序可以基于它实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列等功能。并且Zookeeper可以保证如下分布式一致性特性。

  • 顺序一致性

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

  • 原子性

    所有事务请求的处理结果在整个集群中所有机器上的应用情况是一致的,也就是说,要么集群所有机器都成功应用了某一个事务,那么都没有应用,更不会出现集群中部分机器应用,而另外一部分机器没有应用的情况。

  • 单一视图

    无论客户端连接的是哪个Zookeeper服务器,其看到的是的服务器数据模型都是一致的。

  • 可靠性

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

  • 实时性

    Zookeeper仅仅保证在一定的时间段内,客户端最终一定能从服务端读取到最新的数据状态。

3.1.2 Zookeeper 设计目标

Zookeeper 致力于提供一个高性能、高可用,且具有严格的顺序访问控制能力(主要是写操作的严格顺序性)的分布式协调服务。

目标一:简单的数据模型

Zookeeper使得分布式程序能够通过一个共享的、树型结构的命名空间来进行互相协调,是指Zookeeper服务器内存中的一个数据模型,其由一系列被称为ZNode节点组成,总的来说,其数据模型类似于一个文件系统,而ZNode之间的层级关系,就像文件系统的目录结构一样,与传统的磁盘文件不同,Zookeeper将全量数据存储在内存中,以此来实现提高服务器吞吐、减少延迟的目的。

目标二:可以构建集群

一个Zookeeper集群通常由一组机器组成,一般3~5台机器就可以组成一个可用的Zookeeper集群。

组成Zookeeper的集群的每台机器都会在内存维护当前服务器的状态,并且每台机器之间都相互保持着通信。值得一提的是,只要集群中存在超过一半机器能够正常工作,那么这个集群就是可用即能够对外提供服务。

目标三:顺序访问

对于来自客户端的每个更新请求,Zookeeper都会分配一个全局唯一的递增编号,这个编号反映了所有事务操作的先后顺序。

目标四:高性能

由于Zookeeper将全量数据都存放在内存中,并直接服务于客户端的所有非事务请求,因此它尤其适用于以读操作为主的应用场景。

3.1.3 Zookeeper 基本概念 集群角色

通常在分布式系统中,构成一个集群中的每台机器都有着自己的角色,典型的集群模式是 Master/Slave 模式(主备模式)。在这种模式中,我们把能够处理所有写操作的机器称为Master机器,把所有通过异步复制的方式获取最新数据,并提供读服务的机器称为Slave机器。

而Zookeeper并没有沿用传统的Master/Slave概念,而是引入了Leader、Follower和Observer三种角色。

Zookeeper集群中所有的机器通过Leader选举过程来选定一台被称为"Leader"的机器,Leader服务器为客户端提供读和写服务。

Follower和Observer都能够提供读服务,唯一区别是Observer不参与Leader选举过程,也不参与写操作的"过半写成功"策略,因此Observer再不影响写性能的情况下提升集群的读性能。

会话(Session)

在Zookeeper中,一个客户端连接是客户端与服务端之间的一个TCP长连接。Zookeeper对外的服务端口是2181。

在客户端启动的时候,首先会与服务器建立TCP连接,从第一次建立连接开始,客户端会话也就开始了,通过这个连接,客户端可以通过心跳检测机制与服务端保持有效会话,也能够向服务器发送请求并接收响应,同时还能通过连接接收服务器的Watch事件通知。

当由于服务器压力过大、网络故障或是客户端主动断开连接等各种原因导致与服务器断开连接,之后在sessionTimeout规定的时间内能够重新连接上集群中任意一台服务器,那么之前的会话就继续有效。

数据节点(ZNode)

谈到分布式,我们知道组成集群中的每个服务器代表的是一个"节点"。

然而在Zookeeper中,节点分为两类,

第一类仍然表示的是构成集群的机器,称为机器节点;

第二类则是指数据模型中的数据单元,称为数据节点——ZNode。Zookeeper将所有数据都存放在内存中,其数据模型就是一颗树(ZNode Tree),由斜杆(/)进行分割的路径,就是一个ZNode,例如/foo/path1。每个ZNode上都会保存自己的数据内容,同时保存着一系列元数据。

其中,ZNode分为 持久节点 和 临时节点 两类。

所谓持久节点就是指一旦这个ZNode被创建,除非去主动的删除这个节点,否则这个ZNode节点将一直保存在Zookeeper上。

而临时节点就不一样了,它的生命周期和客户端会话绑定,一旦客户端会话失效,那么这个客户端所创建的所有临时节点都会被移除。

版本

我们知道Zookeeper上的每个ZNode节点都会存储数据,而对应的ZNode节点,Zookeeper都会为其维护一个叫作Stat的数据结构,Stat中记录了ZNode的三个数据版本,分别是

  • version(当前ZNode的版本)
  • cversion(当前ZNode子节点的版本)
  • aversion(当前ZNode的ACL版本)
Watcher

Watcher(监听器),是Zookeeper中一个很重要的特性。

Zookeeper允许用户在指定节点上注册一些Watcher,并且在一些特定事件触发时候,Zookeeper服务器会将事件通知给感兴趣的客户端上。

该机制是Zookeeper实现分布式协调服务的重要特性。

ACL(Access Control Lists)

Zookeeper通过ACL策略来进行权限控制,类似Unix文件系统的权限控制。

Zookeeper定义了如下5种权限:

  • CREATE:创建子节点权限
  • READ:获取节点数据和子节点列表的权限。
  • WRITE:更新节点数据的权限
  • DELETE:删除子节点的权限
  • ADMIN:设置节点ACL权限

尤其要注意的是,CREATE和DELETE这两种权限都是针对子节点的权限控制。

3.2 Zookeeper的ZAB协议 3.2.1 ZAB协议

实际上,Zookeeper不是Paxos算法的一种实现,但事实上Zookeeper并没有完全采用Paxos算法,而是采用称为 Zookeeper Atomic Broadcast (ZAB,Zookeeper原子消息广播协议)来作为数据一致性的核心算法。

Zookeeper实现了一种主备模式的系统架构来保持集群中各副本之间数据的一致性。具体的,Zookeeper使用一个单一的主进程来接收并处理客户端的所有事务请求,并采用ZAB协议,将服务器的变更状态以事务Proposal的形式广播到所有副本进程上去。

ZAB协议的主备模型保证同一时刻只有一个主线程广播服务器的状态变更,因此能够更好地处理客户端大量的并发请求。

另一方面,考虑到在分布式环境下,顺序执行的一些状态变更前后会存在着一定的依赖关系,ZAB协议必须能够保证一个全局的变更序列被顺序应用。

最后考虑到主线程任何时候都有可能出现崩溃退出或重启现象,ZAB还需要做到主线程出现异常,仍能够正常工作。

ZAB协议核心是定义了对于那些改变服务器数据状态的事务请求的处理方式:

所有事务请求必须由一个全局唯一的服务器去协调处理,即Leader服务器,而余下的则称为Follower服务器。

Leader将负责从客户端传来的事务请求转换成事务Proposal(提议),并将Proposal分发给集群中所有Follower。

之后Leader等待所有Follower反馈,一旦超过了半数Follower服务器进行了正确反馈后,

那么Leader将会再次向所有Follower服务器分发Commit消息,要求将前一个Proposal进行提交。

RequestToProposal -> syncProposal -> WaitAck -> HalfAck -> syncCommit

3.2.2 ZAB协议两种模式

ZAB协议包括两种基本模式,分别是崩溃恢复和消息广播。

当整个服务框架在启动过程中,或是当Leader服务器出现网络中断、崩溃退出与重启等异常情况时,ZAB协议就会进入崩溃恢复模式并选举产生新的Leader服务器。当选举产生了新的Leader服务器,同时集群已经有过半机器与Leader服务器完成了状态同步之后,ZAB就会退出崩溃恢复模式。

当集群中有过半服务器与Leader完成了状态同步,那么就可以进入消息广播模式。

当一台同样遵守ZAB协议的服务器加入到集群中,已经有一个Leader在进行消息广播,那么新服务器就会自觉进入恢复模式:找到Leader服务器进行状态同步并一起参与到消息广播流程中去。

Zookeeper设计成只允许唯一的一个Leader服务器进行事务请求的处理。Leader服务器在接收到客户端的事务请求,会生成对应的事务提案并发起一轮广播协议;而集群中的其他的机器接收到服务端的事务请求,那么这些非Leader服务器会首先将这个事务请求转发给Leader服务器。

消息广播

ZAB协议使用的是一个原子广播协议,类似一个二阶段提交过程。

而ZAB协议所涉及的二阶段提交过程略不相同,在ZAB的提交过程中,移除了中断逻辑,意味着我们可以在过半的Follower服务器已经反馈ACK之后就可以提交事务Proposal了,不需要等待集群所有Follower机器都反馈响应。

并解决了二阶段提交中的无法处理Leader服务器崩溃退出而带来的数据不一致问题,因此在ZAB协议添加了崩溃恢复模式来解决这个问题。

另外,整个消息广播协议是基于具有FIFO特性的TCP协议来进行网络通信的,因此能够容易地保证消息广播过程中消息接收和发送的顺序性。


ZXID

在整个消息广播过程中,Leader服务器会给每个事务请求生成对应的Proposal来进行广播,并且在广播之前,Leader服务器会首先为这个事务Proposal分配一个全局单调递增的唯一ID,我们称为事务ID(即ZXID)。为了保证每个消息的因果关系,因此必须将每个事务Proposal按照ZXID的先后顺序来进行排序与处理。

Leader服务器会为每个Follower服务器各自分配一个单独的队列,然后将需要广播的事务Proposal依次放入这些队列,并且按照FIFO策略进行消息发送。

每个Follower接收到Proposal后,都会首先将其以事务日志的形式写入磁盘中去,成功写入并向服务器反馈一个ACK响应。

崩溃恢复

一旦Leader服务器出现了崩溃或者与过半Follower服务器失去了联系,那么就进入崩溃恢复模式。因此在ZAB协议中,需要选举出新的Leader服务器。

基本特性一:ZAB协议需要确保那些已经在Leader服务器上提交的事务最终都被服务器都提交。

但有两个数据不一致的情景需要格外注意:

1)假设一个事务在Leader服务器上已经被提交,而且已经得到了过半Follower服务器的Ack反馈,但是在它将Commit消息发送给Follower机器之前,Leader服务器此时崩溃了,就出现了数据不一致的情况。

比如当Leader服务器将消息C2发出后就立即崩溃退出,针对这种情况,ZAB协议就需要确保事务P2能够最终在所有的服务器上都被提交,否则出现数据不一致。

基本特性二:ZAB协议需要确保丢弃那些只在Leader服务器上被提出的事务。

2)假设初始的Leader服务器Server1在提出了一个事务Proposal3之后就崩溃退出了,从而导致集群中的其他服务器都没有收到这个事务Proposal。

如果在崩溃恢复过程中出现一个需要被丢弃的提案,那么在崩溃恢复结束后需要跳出该事务Proposal,于是,当Server1恢复过来加入到集群中的时候,ZAB协议需要确保丢弃Proposal这个事务。

ZAB是如何处理那些需要被丢弃的事务Proposal的?

在ZAB协议的事务编码ZXID设计中,ZXID是一个64位的数字,其中低32位可以看作是一个简单的单调递增的Counter,对于客户端发来的每个事务,Leader服务器会为其事务Proposal分配+1的编号;而高32位则代表了Leader周期epoch的编号,每当选举出新的Leader服务器,就会从这个服务器中取出本地日志最大事务Proposal的ZXID,并从其解析出epoch值+1,低32位置从0开始生成新的ZXID。

因此基于这样的策略,当一个包含了上一个Leader周期尚未提交的周期过的事务Proposal的服务器已经无法称为Leader,因为Quorum中的机器已经包含了更高的epoch值的事务Proposal,然后与新Leader服务器进行比对,Leader会要求Follower进行一个回退操作——回退到一个确实已经被集群中过半机器提交的最新事务Proposal。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/604088.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号