ZooKeeper 基础

在深入了解ZooKeeper的运作之前,让我们来看看ZooKeeper的基本概念。[1] 我们将在本章中讨论以下主题:
1、Architecture(架构)
2、Hierarchical namespace(层次命名空间)
3、Session(会话)
4、Watch(监视)

ZooKeeper的架构

看看下面的图表。它描述了ZooKeeper的“客户端-服务器架构”。

作为ZooKeeper架构的一部分的每个组件在下表中进行了说明。

部分 描述
Client(客户端)

客户端,分布式应用集群中的一个节点,从服务器访问信息。对于特定的时间间隔,每个客户端向服务器发送消息以使服务器知道客户端是活跃的。

类似地,当客户端连接时,服务器发送确认码。如果连接的服务器没有响应,客户端会自动将消息重定向到另一个服务器。

Server(服务器) 服务器,我们的ZooKeeper总体中的一个节点,为客户端提供所有的服务。向客户端发送确认码以告知服务器是活跃的。
Ensemble ZooKeeper服务器组。形成ensemble所需的最小节点数为3。
Leader 服务器节点,如果任何连接的节点失败,则执行自动恢复。Leader在服务启动时被选举。
Follower 跟随leader指令的服务器节点。

层次命名空间

下图描述了用于内存表示的ZooKeeper文件系统的树结构。ZooKeeper节点称为 znode 。每个znode由一个名称标识,并用路径(/)序列分隔。

  • 在图中,首先有一个由“/”分隔的znode。在根目录下,你有两个逻辑命名空间 config workers

  • config 命名空间用于集中式配置管理,workers 命名空间用于命名。

  • config 命名空间下,每个znode最多可存储1MB的数据。这与UNIX文件系统相类似,但是在ZooKeeper中,父znode也可以存储数据。这种结构的主要目的是存储同步数据并描述znode的元数据。此结构称为 ZooKeeper数据模型

ZooKeeper数据模型中的每个znode都维护着一个 stat 结构。一个stat仅提供一个znode的元数据。它由版本号,操作控制列表(ACL),时间戳和数据长度组成。

  • 版本号 - 每个znode都有版本号,这意味着每当与znode相关联的数据发生变化时,其对应的版本号也会增加。当多个zookeeper客户端尝试在同一znode上执行操作时,版本号的使用就很重要。

  • 操作控制列表(ACL) - ACL基本上是访问znode的认证机制。它管理所有znode读取和写入操作。

  • 时间戳 - 时间戳表示创建和修改znode所经过的时间。它通常以毫秒为单位。ZooKeeper从“事务ID"(zxid)标识znode的每个更改。Zxid 是唯一的,并且为每个事务保留时间,以便你可以轻松地确定从一个请求到另一个请求所经过的时间。

  • 数据长度 - 存储在znode中的数据总量是数据长度。你最多可以存储1MB的数据。

Znode的类型

Znode被分为持久(persistent)节点,顺序(sequential)节点和临时(ephemeral)节点。

  • 持久节点  - 即使在创建该特定znode的客户端断开连接后,持久节点仍然存在。默认情况下,除非另有说明,否则所有znode都是持久的。

  • 临时节点 - 客户端活跃时,临时节点就是有效的。当客户端与ZooKeeper集合断开连接时,临时节点会自动删除。因此,只有临时节点不允许有子节点。如果临时节点被删除,则下一个合适的节点将填充其位置。临时节点在leader选举中起着重要作用。

  • 顺序节点 - 顺序节点可以是持久的或临时的。当一个新的znode被创建为一个顺序节点时,ZooKeeper通过将10位的序列号附加到原始名称来设置znode的路径。例如,如果将具有路径 /myapp 的znode创建为顺序节点,则ZooKeeper会将路径更改为 /myapp0000000001 ,并将下一个序列号设置为0000000002。如果两个顺序节点是同时创建的,那么ZooKeeper不会对每个znode使用相同的数字。顺序节点在锁定和同步中起重要作用。

Session(会话)

会话对于ZooKeeper的操作非常重要。会话中的请求按FIFO顺序执行。一旦客户端连接到服务器,将建立会话并向客户端分配会话ID

客户端以特定的时间间隔发送心跳以保持会话有效。如果ZooKeeper集合在超过服务器开启时指定的期间(会话超时)都没有从客户端接收到心跳,则它会判定客户端死机。

会话超时通常以毫秒为单位。当会话由于任何原因结束时,在该会话期间创建的临时节点也会被删除。

Watch(监视)

监视是一种简单的机制,用于向客户端通知ZooKeeper集合中的更改。客户端可以在读取特定znode时设置watch。watch会向注册的客户端发送有关znode任何更改的通知。

其中包含znode相关数据修改,或者znode的子项中的更改。

watches只触发一次。如果客户端想再次接收通知,则必须通过另一个读取操作来完成。当连接会话过期时,客户端将与服务器断开连接,相关的watches也将被删除。

Zookeeper 工作流

一旦ZooKeeper集合启动,它将等待客户端连接。客户端将连接到ZooKeeper集合中的一个节点。它可以是leader或Follower节点。一旦客户端被连接,节点将向特定客户端分配会话ID并向该客户端发送确认。如果客户端没有收到确认,它将尝试连接ZooKeeper集合中的另一个节点。 一旦连接到节点,客户端将以有规律的间隔向节点发送心跳,以确保连接不会丢失。

读取和写入

  • 如果客户端想要读取特定的znode,它将会向具有znode路径的节点发送读取请求,并且节点通过从其自己的数据库获取来返回所请求的znode。为此,在ZooKeeper集合中读取速度很快。

  • 如果客户端想要将数据存储在ZooKeeper集合中,则会将znode路径和数据发送到服务器。连接的服务器将该请求转发给leader,然后leader将向所有的Follower重新发出写入请求。如果大部分节点成功响应,而写入请求成功,发送成功代码到客户端。 否则,写入请求失败。绝大多数节点被称为 Quorum

集合节点个数

让我们分析在ZooKeeper集合中拥有不同数量的节点的效果。

  • 单个节点,则当该节点故障时,ZooKeeper集合将故障。它将产生“单点故障",不建议在生产环境中使用。

  • 两个节点,一个节点故障。不能称作大多数可用,因为两个中的一个不是多数。

  • 三个节点,一个节点故障。大多数可用。因此,ZooKeeper集合在实际生产环境中必须至少有三个节点。

  • 四个节点,两个节点故障。它将故障。对比与三个节点,多出的节点不起作用。因此,最好添加奇数的节点,例如3,5,7。

写入比读取代价大,因为所有节点都需要写入相同的数据。因此对于读写平衡的环境,拥有较少数量(例如3,5,7)的节点比拥有大量的节点要好。

工作流及组件

组件 描述
写入(write) 写入过程由leader节点处理。leader将写入请求转发到所有znode,并等待znode的回复。如果一半的znode回复,则写入过程完成。
读取(read) 读取由特定连接的znode在内部执行,不需要与集群进行交互。
复制数据库(replicated database) 用于在zookeeper中存储数据。每个znode都有自己的数据库,由于ZooKeeper的一致性,每个znode拥有相同的数据。
Leader leader是负责处理写入请求的znode。
Follower Follower从客户端接收写入请求,并将它们转发到 leader znode。
请求处理器(request processor) 只在leader节点中存在,用于管理来自Follower节点的写入请求。
原子广播(atomic broadcasts)

ZAB协议

A critical component of ZooKeeper is Zab, the ZooKeeper Atomic Broadcast algorithm, which is the protocol that manages atomic updates to the replicas. It is responsible for agreeing on a leader in the ensemble, synchronizing the replicas, managing update transactions to be broadcast, as well as  recovering from a crashed state to a valid state. [4]

原子广播协议

Atomic broadcast protocols are distributed algorithms guaranteed either to correctly broadcast or to abort without side effects.  It is a primitive widely used in distributed computing for group communication.  Atomic broadcast can also be defined as a reliable broadcast that satisfies total order, i.e., that satisfies the following properties:

Validity :  If a correct process broadcasts a message,  then all correct processes will eventually deliver it.

Uniform Agreement :  If a process delivers a message, then all correct processes eventually deliver that message.

Uniform Integrity :  For any message m , every process delivers m at most once, and only if m was previously broadcast by the sender of m .

Uniform Total Order :  If processes p and q both deliver messages m and m ′ , then p delivers m before m ′ if and only if q delivers m before m ′

Zab协议基于分布式协议Paxos,在保留Paxos协议简单性的前提下做了修改,以满足ZooKeeper的要求。

三种状态

协议中存在着三种状态,每个节点都属于以下三种中的一种:[2]

  • Looking:系统刚启动时或Leader崩溃后正处于选举状态
  • Following:Follower节点所处的状态,Follower与Leader处于数据同步阶段
  • Leading:Leader所处状态,当前集群中有一个Leader为主进程

在ZooKeeper的整个生命周期中每个节点都会在Looking、Following、Leading状态间不断转换:

  • ZooKeeper启动时所有节点初始状态为Looking,这时集群会尝试选举出一个Leader节点,选举出的Leader节点切换为Leading状态
  • 当节点发现集群中已经选举出Leader,则该节点会切换到Following状态,然后和Leader节点保持同步
  • 当Follower节点与Leader失去联系时Follower节点则会切换到Looking状态,开始新一轮选举

选举出Leader节点后ZAB进入原子广播阶段,这时Leader为和自己同步的每个节点Follower创建一个操作序列

  • 一个时期一个Follower只能和一个Leader保持同步,Leader节点与Follower节点使用心跳检测来感知对方的存在
  • 当Leader节点在超时时间内收到来自Follower的心跳检测,那Follower节点会一直与该节点保持连接
  • 若超时时间内Leader没有接收到来自过半Follower节点的心跳检测或TCP连接断开,那Leader会结束当前周期的领导,切换到Looking状态,所有Follower节点也会放弃该Leader节点切换到Looking状态,然后开始新一轮选举

四个阶段

ZAB协议定义了选举(election)、发现(discovery)、同步(sync)、广播(Broadcast)四个阶段;ZAB选举(election)时当Follower存在ZXID(事务ID)时判断所有Follower节点的事务日志,只有lastZXID的节点才有资格成为Leader,这种情况下选举出来的Leader总有最新的事务日志,基于这个原因ZoKeeper实现时把发现(discovery)与同步(sync)合并为恢复(recovery)阶段

  • Election:在Looking状态中选举出Leader节点,Leader的lastZXID总是最新的
  • Discovery:Follower节点向准Leader推送FOLLOWERINFO,该信息中包含了上一周期的epoch,接受准Leader的NEWLEADER指令,检查newEpoch有效性,准Leader要确保Follower的epoch与ZXID小于或等于自身的
  • sync:将Follower与Leader的数据进行同步,由Leader发起同步指令,最总保持集群数据的一致性
  • Broadcast:Leader广播Proposal与Commit,Follower接受Proposal与Commit
  • Recovery:在Election阶段选举出Leader后本阶段主要工作就是进行数据的同步,使Leader具有highestZXID,集群保持数据的一致性

(1)选举 Election
election阶段必须确保选出的Leader具有highestZXID,否则在Recovery阶段没法保证数据的一致性,Recovery阶段Leader要求Follower向自己同步数据没有Follower要求Leader保持数据同步,所有选举出来的Leader要具有最新的ZXID。
在选举的过程中会对每个Follower节点的ZXID进行对比只有highestZXID的Follower才可能当选Leader。
选举流程:

  • 每个Follower都向其他节点发送选自身为Leader的Vote投票请求,等待回复
  • Follower接受到的Vote如果比自身的大(ZXID更新)时则投票,并更新自身的Vote,否则拒绝投票
  • 每个Follower中维护着一个投票记录表,当某个节点收到过半的投票时,结束投票并把该Follower选为Leader,投票结束。

ZAB协议中使用ZXID作为事务编号,ZXID为64位数字,低32位为一个递增的计数器,每一个客户端的一个事务请求时Leader产生新的事务后该计数器都会加1,高32位为Leader周期epoch编号,当新选举出一个Leader节点时Leader会取出本地日志中最大事务Proposal的ZXID解析出对应的epoch把该值加1作为新的epoch,将低32位从0开始生成新的ZXID;ZAB使用epoch来区分不同的Leader周期。

(2)恢复 Recovery
在election阶段选举出来的Leader已经具有最新的ZXID,所有本阶段的主要工作是根据Leader的事务日志对Follower节点数据进行更新。

Leader:
Leader生成新的ZXID与epoch,接收Follower发送过来的FOllOWERINFO(含有当前节点的LastZXID)然后往Follower发送NEWLEADER;Leader根据Follower发送过来的LastZXID根据数据更新策略向Follower发送更新指令。
同步策略:

  • SNAP:如果Follower数据太老,Leader将发送快照SNAP指令给Follower同步数据
  • DIFF:Leader发送从Follolwer.lastZXID到Leader.lastZXID议案的DIFF指令给Follower同步数据
  • TRUNC:当Follower.lastZXID比Leader.lastZXID大时,Leader发送从Leader.lastZXID到Follower.lastZXID的TRUNC指令让Follower丢弃该段数据;


Follower:
往Leader发送FOLLOERINFO指令,Leader拒绝就转到Election阶段;接收Leader的NEWLEADER指令,如果该指令中epoch比当前Follower的epoch小那么Follower转到Election阶段;Follower还有主要工作是接收SNAP/DIFF/TRUNC指令同步数据与ZXID,同步成功后回复ACKNETLEADER,然后进入下一阶段;Follower将所有事务都同步完成后Leader会把该节点添加到可用Follower列表中。
SNAP与DIFF用于保证集群中Follower节点已经Committed的数据的一致性,TRUNC用于抛弃已经被处理但是没有Committed的数据。

(3)广播 Broadcast
客户端提交事务请求时Leader节点为每一个请求生成一个事务Proposal,将其发送给集群中所有的Follower节点,收到过半Follower的反馈后开始对事务进行提交,ZAB协议使用了原子广播协议;在ZAB协议中只需要得到过半的Follower节点反馈Ack就可以对事务进行提交,这也导致了Leader几点崩溃后可能会出现数据不一致的情况,ZAB使用了崩溃恢复来处理数字不一致问题;消息广播使用了TCP协议进行通讯所有保证了接受和发送事务的顺序性。广播消息时Leader节点为每个事务Proposal分配一个全局递增的ZXID(事务ID),每个事务Proposal都按照ZXID顺序来处理;
Leader节点为每一个Follower节点分配一个队列按事务ZXID顺序放入到队列中,且根据队列的规则FIFO来进行事务的发送。Follower节点收到事务Proposal后会将该事务以事务日志方式写入到本地磁盘中,成功后反馈Ack消息给Leader节点,Leader在接收到过半Follower节点的Ack反馈后就会进行事务的提交,以此同时向所有的Follower节点广播Commit消息,Follower节点收到Commit后开始对事务进行提交。

ZooKeeper Leader 选举

让我们分析如何在ZooKeeper集合中选举leader节点。考虑一个集群中有N个节点。leader选举的过程如下:[1]

  • 所有节点创建具有相同路径 /app/leader_election/guid_ 的顺序、临时节点。
  • ZooKeeper集合将附加10位序列号到路径,创建的znode将是 /app/leader_election/guid_0000000001,/app/leader_election/guid_0000000002等。
  • 对于给定的实例,在znode中创建最小数字的节点成为leader,而所有其他节点是follower。
  • 每个follower节点监视下一个具有最小数字的znode。例如,创建znode/app/leader_election/guid_0000000008的节点将监视znode/app/leader_election/guid_0000000007,创建znode/app/leader_election/guid_0000000007的节点将监视znode/app/leader_election/guid_0000000006。
  • 如果leader关闭,则其相应的znode/app/leader_electionN会被删除。
  • 下一个在线follower节点将通过监视器获得关于leader移除的通知。
  • 下一个在线follower节点将检查是否存在其他具有最小数字的znode。如果没有,那么它将承担leader的角色。否则,它找到的创建具有最小数字的znode的节点将作为leader。
  • 类似地,所有其他follower节点选举创建具有最小数字的znode的节点作为leader。

leader选举是一个复杂的过程,但ZooKeeper服务使它非常简单。

参考资料:
[1] https://www.w3cschool.cn/zookeeper/zookeeper_fundamentals.html
[2] http://www.solinx.co/archives/435
[3] http://www.tcs.hut.fi/Studies/T-79.5001/reports/2012-deSouzaMedeiros.pdf

Zookeeper 基础、工作流、ZAP协议的更多相关文章

  1. HTTP基础08--追加协议

    消除 HTTP 瓶颈的 SPDY HTTP 的瓶颈 Web 网站为了保存这些新增内容,在很短的时间内就会发生大量的内容更新;为了尽可能实时地显示这些更新的内容,服务器上一有内容更新,就需要直接把那些内 ...

  2. OC基础 代理和协议

    OC基础 代理和协议 1.协议 (1)oc语言中得协议:一组方法列表,不需要我们自己实现,由遵守协议的类来实现协议所定制的方法. (2)协议的使用步骤:制定协议-->遵守协议-->实现协议 ...

  3. zookeeper_02:zookeeper基础

    ZooKeeper基础概述 ZooKeeper维护一个小型的数据节点,这些节点被称为znode,采用类似于文件系统的层级树状结构进行管理. 针对一个znode,没有数据常常表达了重要的信息.比如,在主 ...

  4. java基础篇---HTTP协议

    java基础篇---HTTP协议   HTTP协议一直是自己的薄弱点,也没抽太多时间去看这方面的内容,今天兴致来了就在网上搜了下关于http协议,发现有园友写了一篇非常好的博文,博文地址:(http: ...

  5. zookeeper基础知识整理

    http://blog.csdn.net/pelick/article/details/7269670 http://zookeeper.apache.org/doc/trunk/javaExampl ...

  6. Hadoop系列-zookeeper基础

    目前是刚刚初学完zookeeper,这篇文章主要是简单的对一些基本的概念进行梳理强化. zookeeper基础概念的理解 有时候计算机领域很多名词都是从一长串英文提取首字母缩写而来,但很不幸zooke ...

  7. Unit01: Servlet基础 、 HTTP协议

    Unit01: Servlet基础 . HTTP协议 在页面上输出当前时间 package web; import java.io.IOException; import java.io.PrintW ...

  8. linux 运维基础之http协议详解

    引言 这尼玛博客还得自己在这里写,难受一匹本来排版好的...每次都这样嗨....本内容属于借鉴资源,侵权删! HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系 ...

  9. 网络编程基础:网络基础之网络协议、socket模块

    操作系统(简称OS)基础: 应用软件不能直接操作硬件,能直接操作硬件的只有操作系统:所以,应用软件可以通过操作系统来间接操作硬件 网络基础之网络协议: 网络通讯原理: 连接两台计算机之间的Intern ...

随机推荐

  1. python之路——文件操作

    阅读目录 初窥文件操作基本流程 文件编码 文件的打开模式 文件内的光标移动 with上下文管理 文件的修改 练习 回到顶部 初窥文件操作基本流程 计算机系统分为:计算机硬件,操作系统,应用程序三部分. ...

  2. Python基本特殊方法之__format__

    __format__()方法 __format__()传参方法:someobject.__format__(specification) specification为指定格式,当应用程序中出现&quo ...

  3. Consul做服务发现

    使用Consul做服务发现的若干姿势 https://www.cnblogs.com/bossma/p/9756809.html 从2016年起就开始接触Consul,使用的主要目的就是做服务发现,后 ...

  4. deep Learning 之入门一 (ps:知乎上看到的大佬写的非常好,所以自己记录下)

    作者:Jacky Yang 链接:https://www.zhihu.com/question/26006703/answer/129209540 来源:知乎 著作权归作者所有.商业转载请联系作者获得 ...

  5. 洛谷 P2205 [USACO13JAN]画栅栏Painting the Fence

    传送门 题目大意: 开始站在原点,给出一系列操作 x L/R,表示向左或向右走几步. 最多会移动到离原点1,000,000,000单位远的地方. n次操作,n<=100000 问走过k次的地方有 ...

  6. k8s api server ha 连接配置问题

    常见的lb 负载有硬件的f5 big-ip  ,同时对于互联网公司大家常用的是nginx  haproxy 了解k8s 集群高可用的都知道 api server  是无状态的(etcd 解决了),但是 ...

  7. 用css来写一个背景图片的切换

    代码如下: <!DOCTYPE HTML> <htmllang="en-US"> <head> <meta charset="U ...

  8. Delphi下遍历文件夹下所有文件的递归算法

    {------------------------------------------------------------------------------- 过程名:    MakeFileLis ...

  9. dxjk服务器安装 lamp

    安装Apache:用的下面的安装法命令用的是 yum -y install httpdhttp://blog.csdn.net/kesixin/article/details/72882469 mys ...

  10. .com .cn .org .edu等域名的意义

    在开发的时候遇到了.org的域名,后来就去查了一下,原来这种域名是非盈利组织或者协会的标志 比如: https://getcomposer.org/ https://packagist.org/ ht ...