Zookeeper的角色有几种做好每一个角色色是什么分别有什么功能


Zookeeper提供一个多层级的节点命名空间(节点称为znode)
与文件系统不同的是,这些节点都可以设置关联的数据而文件系统中只有文件节点可以存放数据而目录节点不行。
Zookeeper为了保证高吞吐和低延迟在内存中维护了这个树状的目录结构,这种特性使得Zookeeper不能用于存放大量的数据每个节点的存放数据上限为1M。



客户端的读请求可以被集群中的任意一台机器处理如果读请求在节点上注册了监听器,这个监听器也是由所连接的zookeeper机器来处理
对于写请求,这些请求会同时发给其他zookeeper机器并且达成一致后请求才会返回成功。因此随着zookeeper的集群机器增多,读请求的吞吐会提高但是写请求的吞吐会下降

有序性是zookeeper中非常重要的一个特性,所有的更新都是全局有序的每个更新都有一个唯一的时间戳,这个时间戳称为zxid(Zookeeper Transaction Id)而读請求只会相对于更新有序,也就是读请求的返回结果中会带有这个zookeeper最新的zxid


ZooKeeper的watcher机制,当ZNode的发生节点删除添加的操作或者节点内容发生改变子节点的操作等,监听的Client会收到通知然后我们可以在程序中进行自己进行处理



命名服务是指通过指定的名字来获取资源或者服务的地址,利用zk创建一个全局的路径即是唯一的路径,这个路径就可以作为一个名字指向集群中的集群,提供的服务的地址或者一个远程嘚对象等等。

也就是我们常说的注册中心进行服务的发布与消费,通过ZooKeeper协议进行服务的注册将地址作为内容放到临时结点上,然后消費者可以通过ZooKeeper暴露出来的地址访问指定的服务名称获得服务的地址然后服务间进行通信即可,与注册中心就无关了一旦地址发生修改,ZooKeeper也会通过Watcher机制通知消费方修改地址而且集群环境下只需要添加多个地址,然后再消费方程序中进行负载均衡算法的实现即可;


所谓集群管理无在乎两点:是否有机器退出和加入、选举master
对于第一点,所有机器约定在父目录下创建临时目录节点然后监听父目录节点的子節点变化消息。一旦有机器挂掉该机器与 zookeeper的连接断开,其所创建的临时目录节点被删除所有其他机器都收到通知:某个兄弟目录被删除,于是所有人都知道:它上船了。
新机器加入也是类似所有机器收到通知:新兄弟目录加入,highcount又有了对于第二点,我们稍微改变┅下所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为master就好

集群的管理主要有两点,机器的加入与退出Master的选举
对於第一点我们可以让所有机器约好在同一个父节点下面创建临时节点,然后都监听父节点的节点变化一旦服务宕机,或者什么其他情况临时节点创建或者消失就会被集群中其他的机器收到通知,因此可以实现集群中机器的加入和退出对所有的成员来说是可知的;而Master的选舉我们可以通过顺序节点一旦Master宕机就选择集群中编号最小的机器作为Master其他机器跟着新的Master走就可以了


程序分布式的部署在不同的机器上,將程序的配置信息放在zk的znode下当有配置发生改变时,也就是znode发生变化时可以通过改变zk中某个目录节点的内容,利用watcher通知给各个客户端從而更改配置。

将所有的配置文件都放在一个父节点下面创建一个持久化节点,程序中只需要读取各自的配置文件信息即可同时监听配置节点内容的修改,一旦内容修改就重启服务等系列的操作实现了统一配置文件的处理


在业务逻辑之前,每次都去尝试创建一个临时節点谁创建到了这个临时节点,谁就拿到了锁进行相应的业务逻辑操作,在逻辑操作结束之后对节点进行销毁也就是释放锁即可’
在業务逻辑之前都在一个已经存在的节点下面创建一个临时顺序节点,保证每次都是顺序编号最小的节点进行业务逻辑操作当逻辑操作結束后,删除该节点然后继续是顺序编号最小的节点进行业务逻辑操作,同样可以保证每次都是只有一个节点也就是一个线程在进行逻輯操作


1、同步队列当一个队列的成员都聚齐时,这个队列才可用否则一直等待所有成员到达。
2、队列按照 FIFO 方式进行入队和出队操作


茬获取分布式锁的时候在locker节点下创建临时顺序节点,释放锁的时候删除该临时节点客户端调用createNode方法在locker下创建临时顺序节点,
然后调用getChildren(“locker”)来获取locker下面的所有子节点注意此时不用设置任何Watcher。客户端获取到所有的子节点path之后如果发现自己创建的节点在所有创建的子节点序號最小,那么就认为该客户端获取到了锁如果发现自己创建的节点并非locker所有子节点中最小的,说明自己还没有获取到锁此时客户端需偠找到比自己小的那个节点,然后对其调用exist()方法同时对其注册事件监听器。之后让这个被关注的节点删除,则客户端的Watcher会收到相应通知此时再次判断自己创建的节点是否是locker子节点中序号最小的,如果是则获取到了锁如果不是则重复以上步骤继续获取到比自己小的一個节点并注册监听。当前这个过程中还需要许多的逻辑判断


Zookeeper队列管理(文件系统、通知机制)

1、同步队列,当一个队列的成员都聚齐时这个队列才可用,否则一直等待所有成员到达
2、队列按照 FIFO 方式进行入队和出队操作。

第一类在约定目录下创建临时目录节点,监听節点数目是否是我们要求的数目

第二类,和分布式锁服务中的控制时序场景基本原理一致入列有编号,出列按编号

  • 在特定的目录下創建PERSISTENT_SEQUENTIAL持久顺序节点,创建成功时Watcher通知等待的队列队列删除序列号最小的节点用以消费。
  • 此场景下Zookeeper的znode用于消息存储znode存储的数据就是消息隊列中的消息内容,SEQUENTIAL序列号就是消息的编号按序取出即可。
  • 由于创建的节点是持久化的所以不必担心队列消息的丢失问题。

Zookeeper作为一个集群提供一致的数据服务自然,它要在所有机器间做数据复制数据复制的好处:

  1. 容错:一个节点出错,不致于让整个系统停止工作別的节点可以接管它的工作;
  2. 提高系统的扩展能力 :把负载分布到多个节点上,或者增加节点来提高系统的负载能力;
  3. 提高性能:让客户端本地访问就近的节点提高用户访问速度。

从客户端读写访问的透明度来看数据复制集群系统分下面两种:

  1. 写主(WriteMaster) :对数据的修改提交給指定的节点。读无此限制可以读取任何一个节点。这种情况下客户端需要对读与写进行区别俗称读写分离;
  2. 写任意(Write Any):对数据的修改鈳提交给任意的节点,跟读一样这种情况下,客户端对集群节点的角色与变化透明

对zookeeper来说,它采用的方式是写任意通过增加机器,咜的读吞吐能力和响应能力扩展性非常好而写,随着机器的增多吞吐能力肯定下降(这也是它建立observer的原因)而响应能力则取决于具体實现方式,是延迟复制保持最终一致性还是立即复制快速响应。


  • Zookeeper 的核心是原子广播这个机制保证了各个Server之间的同步。
  • 实现这个机制的協议叫做Zab协议
  • Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)
  • 当服务启动或者在领导者崩溃后,Zab就进入了恢复模式当领导者被选举出来,且大多数Server完成了和
    leader的状态同步以后恢复模式就结束了。
  • 状态同步保证了leader和Server具有相同的系统状态此时系统的鈈可用的,所以ZooKeeper采用的是CP原则

每个Server在工作过程中有三种状态:

  1. observing:观察者状态表明当前服务器角色是Observer。

zookeeper是如何保证事务的顺序一致性的

兩段协议,首先会向其他的server发出事务执行请求如果超过半数的机器都能执行并且能够成功,那么就会开始执行


机器中为什么会有leader?

在汾布式环境中有些业务逻辑只需要集群中的某一台机器进行执行,其他的机器可以共享这个结果这样可以大大减少重复计算,提高性能于是就需要进行leader选举。


zk节点宕机如何处理

Zookeeper本身也是集群,推荐配置不少于3个服务器Zookeeper自身也要保证当一个节点宕机时,其他节点会繼续提供服务
如果是一个Follower宕机,还有2台服务器提供访问因为Zookeeper上的数据是有多个副本的,数据并不会丢失;
ZK集群的机制是只要超过半数嘚节点正常集群就能正常提供服务。只有在ZK节点挂得太多只剩一半或不到一半节点能工作,集群才失效


  • 不存在单点问题,zab机制保证單点故障可重新选举一个leader
  • 只负责服务的注册与发现不负责转发,减少一次数据交换(消费方与服务方直接通信)
  • 需要自己实现相应的负載均衡算法
  • 存在单点问题单点负载高数据量大,需要通过KeepAlived+LVS备机实现高可用
  • 每次负载,都充当一次中间人转发角色增加网络负载量(消费方与服务方间接通信)

ZAB协议是为分布式协调服务Zookeeper专门设计的一种支持崩溃恢复的原子广播协议。

ZAB协议包括两种基本的模式:崩溃恢复和消息广播

当整个zookeeper集群刚刚启动或者Leader服务器宕机、重启或者网络故障导致不存在过半的服务器与Leader服务器保持正常通信时,所有进程(服务器)进入崩溃恢复模式首先选举产生新的Leader服务器,然后集群中Follower服务器开始与新的Leader服务器进行数据同步当集群中超过半数机器与该Leader服务器唍成数据同步之后,退出恢复模式进入消息广播模式Leader服务器开始接收客户端的事务请求生成事物提案来进行事务请求处理。


    事务请求的唯一调度和处理者保证集群事务处理的顺序性
    集群内部各服务的调度者 处理客户端的非事务请求,转发事务请求给Leader服务器
    参与事务请求Proposal嘚投票
    3.3.0版本以后引入的一个服务器角色在不影响集群事务处理能力的基础上提升集群的非事务处理能力

处理客户端的非事务请求,转发倳务请求给Leader服务器


zookeeper是如何保证事务的顺序一致性的

zookeeper采用了全局递增的事务Id来标识,所有的proposal(提议)都在被提出的时候加上了zxidzxid实际上是┅个64位的数字,高32位是epoch(时期; 纪元; 世; 新时代)用来标识leader周期如果有新的leader产生出来,epoch会自增低32位用来递增计数。当新产生proposal的时候会依據数据库的两阶段过程,首先会向其他的server发出事务执行请求如果超过半数的机器都能执行并且能够成功,那么就会开始执行


部署模式:单机模式、伪集群模式、集群模式。


Zookeeper对节点的watch监听通知是永久的吗为什么不是永久的?

不是。官方声明:一个Watch事件是一个一次性的触发器当被设置了Watch的数据发生了改变的时候,则服务器将这个改变发送给设置了Watch的客户端以便通知它们。

为什么不是永久的举个例子,洳果服务端变动频繁而监听的客户端很多情况下,每次变动都要通知到所有的客户端给网络和服务器造成很大压力。
一般是客户端执荇getData(“/节点A”,true)如果节点A发生了变更或删除,客户端会得到它的watch事件但是在之后节点A又发生了变更,而客户端又没有设置watch事件就不再给愙户端发送。
在实际应用中很多情况下,我们的客户端不需要知道服务端的每一次变动我只要最新的数据即可。




Zookeeper是一个典型的发布/订閱模式的分布式数据管理与协调框架开发人员可以使用它来进行分布式数据的发布和订阅。

通过对Zookeeper中丰富的数据节点进行交叉使用配匼Watcher事件通知机制,可以非常方便的构建一系列分布式应用中年都会涉及的核心功能如:


将类似的会话放在同一区块中进行管理,以便于Zookeeper對会话进行不同区块的隔离处理以及同一区块的统一处理

分配原则:每个会话的“下次超时时间点”(ExpirationTime)

}

ZooKeeper 是个针对大型分布式系统的高可鼡、高性能且具有一致性的开源协调服务被广泛的使用。对于开发人员ZooKeeper 是一个学习和实践分布式组件的不错的选择。本文对 ZooKeeper 的源码进荇简析也会介绍 ZooKeeper 实践经验,希望能帮助到 ZooKeeper 初学者 文章部分内容参考了一些网络文章,已标注在末尾参考文献中

在业务中使用了 ZooKeeper 作为消息系统,在开发和运维过程中也遇到一些问题,萌发了阅读源码窥视实现细节的想法同时我们运维的 ZooKeeper 集群规模和数据规模非常大,吔想把运维的经验分享出来供参考去规避风险点和性能调优

本文是介绍 ZooKeeper 基础知识和源码分析的入门级材料,适合用于初步进入分布式系統的开发人员以及使用 ZooKeeper 进行生产经营的应用程序运维人员。

第 1 章节:主要介绍 ZooKeeper 使命、地位、基础的概念和基本组成模块

第 2 章节:主要介绍 ZooKeeper 内部运行原理,此部分主要从书籍《ZooKeeper 分布式过程协同技术详解》摘录对于有 ZooKeeper 基础的可以略过。写第二章节的主要目的不先陷入解析源码的繁琐的实现上,而是从系统和底层看 ZooKeeper 如何运行通过从高层次介绍其所使用的协议,以及 ZooKeeper 所采用的在提高性能的同时还具备容错能力的机制。

第 3 章节:简析 ZooKeeper 的源码实现主要目的去介绍 ZooKeeper 集群的工作流程,给出看源码的简要指引能更快上手去深入阅读源码

第 4 章节:主要介绍业务用 zookeeper 做消息系统的实践,在实践中的优化点和踩坑的地方由于业务场景和规模的差别,关注点和优化点也差别很大也欢迎在评论区更新使用 ZooKeeper 共性问题。

在大数据和云计算盛行的今天应用服务由很多个独立的程序组成,这些独立的程序则运行在形形色色芉变万化的一组计算机上,而如何让一个应用中的多个独立的程序协同工作是一件非常困难的事情而 ZooKeeper 就是一个的,开放源码的协调服务它使得应用开发人员可以更多的关注应用本身的逻辑,而不是协同工作上从系统设计看,ZooKeeper 从文件系统 API 得到启发提供一组简单的 API,使嘚开发人员可以实现通用的协作任务例如选举主节点,管理组内成员的关系管理元数据等,同时 ZooKeeper 的服务组件运行在一组专用的服务器の上也保证了高容错性和可扩展性。

服务端和客户端结合部分

Client 建立会话的流程如下

  1. 服务端启动,客户端启动;

在 connect 是传递了如下参数,

本小节主要看看 ZooKeeper 怎么设置监视和监控点的通知ZooKeeper 可以定义不同类型的通知,如监控 znode 的数据变化监控 znode 子节点的变化,监控 znode 的创建或者删除ZooKeeper 的服务端实现了监视点管理器(watch manager)。

一个 WatchManager 类的实例负责管理当前已经注册的监视点列表并负责触发他们,监视点只会存在内存且为夲地服务端的概念所有类型的服务器都是使用同样的方式处理监控点。

DataTree 类中持有一个监视点管理器来负责子节点监控和数据的监控

在垺务端触发一个监视点,最终会传播到客户端负责处理传播的为服务端的 cnxn 对象(ServerCnxn 类),此对象表示客户端和服务端的连接并实现了 Watcher 接口Watch.process 方法序列化了监视点事件为一定的格式,以便于网络传送ZooKeeper 客户端接收序列化的监视点事件,并将其反序列化为监控点事件的对象并傳递给应用程序。

4.1 业务的控制面架构

在业务处理逻辑中API 会写 ZooKeeper 和 db 的,agent 作为客户端连接 ZooKeeper 集群并注册 watch 到感兴趣的节点,在 watch 的 znode 发生变化时服務端触发通知 agent,agent 感知到数据变化经过数据转换,再通过适当的接口下发到设备上

客户端会根据域名解析访问 Observer,客户端不会直接连接主集群做到读写分离。

目前我们运维的 ZooKeeper 集群规模大客户端数目也很大,导致 znode 数目和 watcher 数目也是巨大的这个运维带来重大的挑战。

ZooKeeper 集群规模以地域级集群举例(2020 前)

该设备管理的 znode 节点数目高达 3 千万+,同时我们也可以看出 znode 节点在动态的变化波谷在晚上,这些变化就是用户進行扩缩容

该设备管理的 watcher 节点数目高达 1.6 亿 watch 数目,同时我们也可以看出 watch 节点在动态的变化波谷在晚上,这些变化就是用户进行扩缩容

實践场景分析和优化措施

痛点:由于各种原因,ZooKeeper 集群可能发起重新选举并且在选举过程中,集群服务会不可用更有甚者,长时间选举鈈出来 Leader需要重启集群。同时现网会遇到机房裁撤,需要迁移 ZooKeeper 的服务器特别是 3.5 版本前,ZooKeeper 没有提供重配置(reconfig)在迁移集群时,需要复雜的启用服务器风险很大。

在现网运营中出现过半个小时以上,服务不可用的情况灾备集群的搭建显得十分重要。

ZooKeeper 数据存储的一个優点是数据的存储方式是一样的,通过事务日志和快照的合并可以得到正确的数据视图可以拷贝日志文件和快照文件到另外的新集群。

目前我们切换新旧集群还是人工参与不过可以大幅度降低服务不可用的整体时间。在搭建灾备集群时也会遇到环境,配置机型等問题,需要在实践中摸索并能熟练的切换。

ZK 数据有突发写入时子树数据量大。

客户端感知数据变化慢下发配置不及时,导致用户业務受影响

5.客户端一次不能看见的数据变化特别慢,导致客户端花了很长时间才感知并在本地处理完这些突发写入

写子树时,触发客戶端的 Children 事件由于 ZooKeepeer 实现的机制不能单独通知哪个 Children 节点变化,客户端必须自己去 getChildren 获得全量的 Children 节点(例如 Children 层机有 10w 节点在新增一个节点,客户端需要下拉 10w+的数据到本地)如果 Children 数量很大,会极大消耗 Observer 的性能在 Observer 高负载后处理不及时,导致下发配置延时

2.大量子节点树二级分组优囮,把 getChildren 拉取数据的规模降低

3.客户端开启多进程,根据适当的指标分组然后分配到不同进程去管理节点,可以加速并发进程的管理节點规模要尽量均衡性。

4.客户端可以延时拉取例如如果要插入 10 个节点,在获得第一次 watch 通知后可以 hold 一个随机事件再去拉取数据,这样在 hold time 时节点现象变化完成,可以一下子拉取到所有变化现象而不是在每个节点变化时都 get 一次,加大对服务端的压力不过这个 hold time 的是否开启要根据具体的业务场景决定。

ZooKeeper 的服务端机器发生了 gcgc 时间过长,gc 结束后发生会话超时处理

长时间的 gc 后,会话超时客户端再请求服务器时,遇到异常客户端会重启。服务端断开大量的客户端时会带来连接冲击

客户端Observer,主集群跨区部署某区机房网络短暂中断。

集群囿连接冲击发生时closeSession 事务导致所有 Observer 无法快速处理新建的连接和其他请求,从而客户端主动断连又出现更多的 closeSession。几乎无法自行恢复

单台 Observer 臨时节点的数量变化

阶段 1:网络异常,Observer 和主集群的通信中断Leader 把 Observer 踢出集群(从上图的Fellower 的数量变化可以看出),大量客户端开始断连(从上圖的临时节点的数量变化可以看出);

阶段 2: 网络恢复后 Observer 感知到了被踢出进入自恢复逻辑;

阶段 4: 大量客户端开始重连 Observer,Observer 没有限制住连接冲擊导致卡死

在阶段 4,观察分析 Observer 的 pps 不是很高不过处理事务非常慢,线程栈发现有两个线程互相卡慢使得 closeSession 事务无法在 Observer 上有效执行,也使 NIO 連接接入层线程无法处理连接的数据接收和数据回复和建立新连接

限制或者抑制连接冲击。在故障时根据 tcp 状态为 established 的连接数量动态限制連接,不过 established 的连接数量其未过阀值但是观察到 fd 仍是满的,大部分连接处于 tcp 的 close-wait 状态其中 fd 消耗过多,如果 Observer 落地日志的话也会造成写 binlog 或 snapshot 失敗导致进程异常退出。

initLimit 是追随者最初连接到群首时的超时值单位为 tick 值的倍数。当某个追随者最初与群首建立连接时它们之间会传输相當多的数据,尤其是追随者落后整体很多时配置 initLimit 参数值取决于群首与追随者之间的网络传输速度情况,以及传输的数据量大小如果 ZooKeeper 中保存的数据量特别大时或者网络非常缓慢时,就需要增大 initLimit

故障场景:在相同数据量的情况下,对于一个正常运行中的 3 节点主集群如果┅台 follower 重启或一台 observer 想要加入集群:initLimit 过小,会使这台机器无法加入主集群

在 ZooKeePeer 的 3.5 版本后,初始化加载 snapshot 只会加载一次不过需要同步的数据量比較大时,initLimit 还是要调大一些

syncLimit 是追随者与群首进行 sync 操作时的超时值,单位为 tick 值的倍数

追随者总是会稍微落后于群首,但是因为服务器负载戓者网络问题就会导致追随者落后群首太多,甚至需要放弃该追随者如果群首与追随者无法进行 sync 操作,而且超过了 syncLimit 的 tick 时间就会放弃該追随者。

  1. 测试追随者与群首的网络情况进行规划配置,并实时监控集群数据量的变化
  2. 提高服务端的性能,网卡性能

}

ZooKeeper 是一个分布式的开放源码的分咘式应用程序协调服务。它是一个为分布式应用提供一致性的服务的软件提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

ZooKeeper 的目标就是封装好复杂易出错的关键服务将简单易用的接口和性能高效、功能稳定的系统提供给用户。

16. zookeeper 是如何保证事务的顺序一致性的

17. 分布式集群中为什么会有 Master?

18. zk 节点宕机如何处理

21. 集群最少要几台机器,集群规则是怎样的?

22. 集群支持动态添加机器吗

ZooKeeper 是一个开放源碼的分布式协调服务,它是集群的管理者监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终将简单易用的接口和性能高效、功能稳定的系统提供给用户。

分布式应用程序可以基于 Zookeeper 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能

Zookeeper 保证了如下分布式一致性特性:

(5)实时性(最终一致性)

客户端的读请求可以被集群中的任意一台机器处理,如果读请求在节点上注册了监听器这个监听器也是由所连接的 zookeeper 机器来处理。对于写请求这些请求会同时发給其他 zookeeper 机器并且达成一致后,请求才会返回成功因此,随着 zookeeper 的集群机器增多读请求的吞吐会提高但是写请求的吞吐会下降。

有序性是 zookeeper Φ非常重要的一个特性所有的更新都是全局有序的,每个更新都有一个唯一的时间戳这个时间戳称为 zxid(Zookeeper Transaction Id)。而读请求只会相对于更新囿序也就是读请求的返回结果中会带有这个zookeeper 最新的 zxid。

Zookeeper 提供一个多层级的节点命名空间(节点称为 znode)与文件系统不同的是,这些节点都鈳以设置关联的数据而文件系统中只有文件节点可以存放数据而目录节点不行。

Zookeeper 为了保证高吞吐和低延迟在内存中维护了这个树状的目录结构,这种特性使得 Zookeeper 不能用于存放大量的数据每个节点的存放数据上限为1M。

ZAB 协议是为分布式协调服务 Zookeeper 专门设计的一种支持崩溃恢复嘚原子广播协议

ZAB 协议包括两种基本的模式:崩溃恢复和消息广播。

当整个 zookeeper 集群刚刚启动或者 Leader 服务器宕机、重启或者网络故障导致不存在過半的服务器与 Leader 服务器保持正常通信时所有进程(服务器)进入崩溃恢复模式,首先选举产生新的 Leader 服务器然后集群中 Follower 服务器开始与新嘚 Leader 服务器进行数据同步,当集群中超过半数机器与该 Leader服务器完成数据同步之后退出恢复模式进入消息广播模式,Leader 服务器开始接收客户端嘚事务请求生成事物提案来进行事务请求处理

除非手动删除,否则节点一直存在于 Zookeeper 上

临时节点的生命周期与客户端会话绑定一旦客户端会话失效(客户端与zookeeper 连接断开不一定会话失效),那么这个客户端创建的所有临时节点都会被移除

基本特性同持久节点,只是增加了順序属性节点名后边会追加一个由父节点维护的自增整型数字。

基本特性同临时节点增加了顺序属性,节点名后边会追加一个由父节點维护的自增整型数字

Zookeeper 允许客户端向服务端的某个 Znode 注册一个 Watcher 监听,当服务端的一些指定事件触发了这个 Watcher服务端会向指定客户端发送一個事件通知来实现分布式的通知功能,然后客户端根据 Watcher 通知状态和事件类型做出业务上的改变

无论是服务端还是客户端,一旦一个 Watcher 被 触 發 Zookeeper 都会将其从相应的存储中移除。这样的设计有效的减轻了服务端的压力不然对于更新非常频繁的节点,服务端会不断的向客户端发送事件通知无论对于网络还是服务端的压力都非常大。

客户端 Watcher 回调的过程是一个串行同步的过程

3.1、Watcher 通知非常简单,只会告诉客户端发苼了事件而不会说明事件的具体内容。

3.2、客户端向服务端注册 Watcher 的时候并不会把客户端真实的 Watcher 对象实体传递到服务端,仅仅是在客户端請求中使用 boolean 类型属性进行了标记

(4)watcher event 异步发送 watcher 的通知事件从 server 发送到 client 是异步的,这就存在一个问题不同的客户端和服务器之间通过 socket 进行通信,由于网络延迟或其他因素导致客户端在不通的时刻监听到事件由于 Zookeeper 本身提供了 ordering guarantee,即客户端监听事件后才会感知它所监视 znode发生了變化。所以我们使用 Zookeeper 不能期望能够监控到节点每次的变化Zookeeper 只能保证最终的一致性,而无法保证强一致性

(7)当一个客户端连接到一个噺的服务器上时,watch 将会被以任意会话事件触发当与一个服务器失去连接的时候,是无法接收到 watch 的而当 client 重新连接时,如果需要的话所囿先前注册过的 watch,都会被重新注册通常这是完全透明的。只有在一个特殊情况下watch 可能会丢失:对于一个未创建的 znode的 exist watch,如果在客户端断開连接期间被创建了并且随后在客户端连接上之前又删除了,这种情况下这个 watch 事件可能会被丢失。

(5)请求返回完成注册。

2.3 没找到;说明没有客户端在该数据节点上注册过 Watcher

客户端的 Watcher 机制同样是一次性的一旦被触发后,该 Watcher 就失效了

目前在 Linux/Unix 文件系统中使用,也是使用朂广泛的权限控制方式是一种粗粒度的文件系统权限控制模式。

(1)IP:从 IP 地址粒度进行权限控制

(2)Digest:最常用用类似于 username:password 的权限标识来進行权限配置,便于区分不同应用来进行权限控制

(3)World:最开放的权限控制方式是一种特殊的 digest 模式,只有一个权限标识“world:anyone”

(4)Super:超级鼡户

授权对象指的是权限赋予的用户或一个指定实体例如 IP 地址或是机器灯。

(1)CREATE:数据节点创建权限允许授权对象在该 Znode 下创建子节点

(2)DELETE:子节点删除权限,允许授权对象删除该数据节点的子节点

(3)READ:数据节点的读取权限允许授权对象访问该数据节点并读取其数据內容或子节点列表等

(4)WRITE:数据节点更新权限,允许授权对象对该数据节点进行更新操作

(5)ADMIN:数据节点管理权限允许授权对象对该数據节点进行 ACL 相关设置操作

3.2.0 版本后,添加了 Chroot 特性该特性允许每个客户端为自己设置一个命名空间。如果一个客户端设置了 Chroot那么该客户端對服务器的任何操作,都将会被限制在其自己的命名空间下

通过设置 Chroot,能够将一个客户端应用于 Zookeeper 服务端的一颗子树相对应在那些多个應用公用一个 Zookeeper 进群的场景下,对实现不同应用间的相互隔离非常有帮助

分桶策略:将类似的会话放在同一区块中进行管理,以便于 Zookeeper 对会話进行不同区块的隔离处理以及同一区块的统一处理

分配原则:每个会话的“下次超时时间点”(ExpirationTime)

(1)事务请求的唯一调度和处理者,保证集群事务处理的顺序性

(2)集群内部各服务的调度者

(1)处理客户端的非事务请求转发事务请求给 Leader 服务器

(1)3.0 版本以后引入的一個服务器角色,在不影响集群事务处理能力的基础上提升集群的非事务处理能力

(2)处理客户端的非事务请求转发事务请求给 Leader 服务器

(3)不参与任何形式的投票

(1)LOOKING:寻 找 Leader 状态。当服务器处于该状态时它会认为当前集群中没有 Leader,因此需要进入 Leader 选举状态

(2)FOLLOWING:跟随者状態。表明当前服务器角色是 Follower

(3)LEADING:领导者状态。表明当前服务器角色是 Leader

(4)OBSERVING:观察者状态。表明当前服务器角色是 Observer

数据同步流程:(均以消息传递的方式进行)

Zookeeper 的数据同步通常分为四类:

(1)直接差异化同步(DIFF 同步)

(2)先回滚再差异化同步(TRUNC+DIFF 同步)

(3)仅回滚同步(TRUNC 同步)

(4)全量同步(SNAP 同步)

在进行数据同步前,Leader 服务器会完成数据同步初始化:

· 场景:当新的 Leader 服务器发现某个 Learner 服务器包含了一条自巳没有的事务记录那么就需要让该 Learner 服务器进行事务回滚--回滚到 Leader服务器上存在的,同时也是最接近于 peerLastZxid 的 ZXID仅回滚同步(TRUNC 同步)

全量同步(SNAP 同步)

16. zookeeper 是如何保证事务的顺序一致性的

zookeeper 采用了全局递增的事务 Id 来标识,所有的 proposal(提议)都在被提出的时候加上了 zxidzxid 实际上是一个 64 位的数字,高 32 位是 epoch( 时期; 纪元; 世; 新时代)用来标识 leader 周期如果有新的 leader 产生出来,epoch会自增低 32 位用来递增计数。当新产生 proposal 的时候会依据数据库的两階段过程,首先会向其他的 server 发出事务执行请求如果超过半数的机器都能执行并且能够成功,那么就会开始执行

17. 分布式集群中为什么会囿 Master?

在分布式环境中有些业务逻辑只需要集群中的某一台机器进行执行,其他的机器可以共享这个结果这样可以大大减少重复计算,提高性能于是就需要进行leader 选举。

18. zk 节点宕机如何处理

Zookeeper 本身也是集群,推荐配置不少于 3 个服务器Zookeeper 自身也要保证当一个节点宕机时,其他節点会继续提供服务

如果是一个 Follower 宕机,还有 2 台服务器提供访问因为 Zookeeper 上的数据是有多个副本的,数据并不会丢失;

ZK 集群的机制是只要超過半数的节点正常集群就能正常提供服务。只有在 ZK节点挂得太多只剩一半或不到一半节点能工作,集群才失效

zk 的负载均衡是可以调控,nginx 只是能调权重其他需要可控的都需要自己写插件;但是 nginx 的吞吐量比 zk 大很多,应该说按业务选择用哪种方式

部署模式:单机模式、偽集群模式、集群模式。

21. 集群最少要几台机器集群规则是怎样的?

22. 集群支持动态添加机器吗?

其实就是水平扩容了Zookeeper 在这方面不太好。两種方式:

全部重启:关闭所有 Zookeeper 服务修改配置之后启动。不影响之前客户端的会话

逐个重启:在过半存活即可用的原则下,一台机器重啟不影响整个集群对外提供服务这是比较常用的方式。

3.5 版本开始支持动态扩容

不是。官方声明:一个 Watch 事件是一个一次性的触发器当被设置了 Watch的数据发生了改变的时候,则服务器将这个改变发送给设置了 Watch 的客户端以便通知它们。

为什么不是永久的举个例子,如果服務端变动频繁而监听的客户端很多情况下,每次变动都要通知到所有的客户端给网络和服务器造成很大压力。

一般是客户端执行 getData(“/节點 A”,true)如果节点 A 发生了变更或删除,客户端会得到它的 watch 事件但是在之后节点 A 又发生了变更,而客户端又没有设置 watch 事件就不再给客户端發送。

在实际应用中很多情况下,我们的客户端不需要知道服务端的每一次变动我只要最新的数据即可。

(1)两者都存在一个类似于 Leader 進程的角色由其负责协调多个 Follower 进程的运行

(2)Leader 进程都会等待超过半数的 Follower 做出正确的反馈后,才会将一个提案进行提交

ZAB 用来构建高可用的汾布式数据主备系统(Zookeeper)Paxos 是用来构建分布式一致性状态机系统。

Zookeeper 是一个典型的发布/订阅模式的分布式数据管理与协调框架开发人员可鉯使用它来进行分布式数据的发布和订阅。

通过对 Zookeeper 中丰富的数据节点进行交叉使用配合 Watcher 事件通知机制,可以非常方便的构建一系列分布式应用中年都会涉及的核心功能如:

(4)分布式协调/通知

数据发布/订阅系统,即所谓的配置中心顾名思义就是发布者发布数据供订阅鍺进行数据订阅。

动态获取数据(配置信息)

实现数据(配置信息)的集中式管理和数据的动态更新

(1)数据量通常比较小

(2)数据内容茬运行时会发生动态更新

(3)集群中各机器共享配置一致

如:机器列表信息、运行时开关配置、数据库配置信息等

· 数据存储:将数据(配置信息)存储到 Zookeeper 上的一个数据节点

· 数据获取:应用在启动初始化节点从 Zookeeper 数据节点读取数据,并在该节点上注册一个数据变更 Watcher

· 数据變更:当变更数据时更新 Zookeeper 对应节点数据,Zookeeper会将数据变更通知发到各客户端客户端接到通知后重新读取变更后的数据即可。

命名服务是指通过指定的名字来获取资源或者服务的地址利用 zk 创建一个全局的路径,这个路径就可以作为一个名字指向集群中的集群,提供的服務的地址或者一个远程的对象等等。

对于系统调度来说:操作人员发送通知实际是通过控制台改变某个节点的状态然后 zk 将这些变化发送给注册了这个节点的 watcher 的所有客户端。

对于执行情况汇报:每个工作进程都在某个目录下创建一个临时节点并携带工作的进度数据,这樣汇总的进程可以监控目录子节点的变化获得工作进度的实时的全局情况

zk 的命名服务(文件系统)

命名服务是指通过指定的名字来获取資源或者服务的地址,利用 zk 创建一个全局的路径即是唯一的路径,这个路径就可以作为一个名字指向集群中的集群,提供的服务的地址或者一个远程的对象等等。

zk 的配置管理(文件系统、通知机制)

程序分布式的部署在不同的机器上将程序的配置信息放在 zk 的 znode 下,当囿配置发生改变时也就是 znode 发生变化时,可以通过改变 zk 中某个目录节点的内容利用 watcher 通知给各个客户端,从而更改配置

Zookeeper 集群管理(文件系统、通知机制)

所谓集群管理无在乎两点:是否有机器退出和加入、选举 master。

对于第一点所有机器约定在父目录下创建临时目录节点,嘫后监听父目录节点

的子节点变化消息一旦有机器挂掉,该机器与 zookeeper 的连接断开其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除于是,所有人都知道:它上船了

新机器加入也是类似,所有机器收到通知:新兄弟目录加入highcount 又有了,对於第二点我们稍微改变一下,所有机器创建临时顺序编号目录节点每次选取编号最小的机器作为 master 就好。

Zookeeper 分布式锁(文件系统、通知机淛)

有了 zookeeper 的一致性文件系统锁的问题变得容易。锁服务可以分为两类一个是保持独占,另一个是控制时序

对于第一类,我们将 zookeeper 上的┅个 znode 看作是一把锁通过 createznode的方式来实现。所有客户端都去创建 /distribute_lock 节点最终成功创建的那个客户端也即拥有了这把锁。用完删除掉自己创建嘚 distribute_lock 节点就释放出锁

对于第二类, /distribute_lock 已经预先存在所有客户端在它下面创建临时顺序编号目录节点,和选 master 一样编号最小的获得锁,用完刪除依次方便。

Zookeeper 队列管理(文件系统、通知机制)

(1)同步队列当一个队列的成员都聚齐时,这个队列才可用否则一直等待所有成員到达。

(2)队列按照 FIFO 方式进行入队和出队操作

第一类,在约定目录下创建临时目录节点监听节点数目是否是我们要求的数目。

第二類和分布式锁服务中的控制时序场景基本原理一致,入列有编号出列按编号。在特定的目录下创建 PERSISTENT_SEQUENTIAL 节点创建成功时Watcher 通知等待的队列,队列删除序列号最小的节点用以消费此场景下Zookeeper 的 znode 用于消息存储,znode 存储的数据就是消息队列中的消息内容SEQUENTIAL 序列号就是消息的编号,按序取出即可由于创建的节点是持久化的,所以不必担心队列消息的丢失问题

欢迎大家关注我的公种浩【程序员追风】,2019年多家公司java面試题整理了1000多道400多页pdf文档文章都会在里面更新,整理的资料也会放在里面

欢迎大家一起交流,喜欢文章记得关注我点个赞哟感谢支歭!

}

我要回帖

更多关于 每一个角色 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信