ZooKeeper概念与应用
Zookeeper是开源的分布式协调服务,提供了分布式数据一致性的解决方案。
Zookeeper 可用作配置中心和分布式锁服务,在 Dubbo、Kafka、Spark等分布式集群上得到广泛应用。
ZNode
Zookeeper的数据模型为树状结构,树的节点被称作ZNode。
Zookeeper使用路径来唯一标识ZNode,类似于Unix文件系统中的绝对路径。路径必须以/开头,由Unicode字符串组成,如/myapp/master/0。
每一个ZNode维护着三部分数据:
- stat: 节点状态信息,包括版本、更改时间、访问控制等
- data: 节点的内容数据,Zookeeper限制每个节点数据不超过1M。Zookeeper设计用来进行协调调度,请勿在其中存放大量数据。
- children: 该ZNode的子节点。
每个节点都有独立的访问控制列表(Access Control List, ACL), 来控制用户对本节点的访问权限。
每个ZNode都维护着三个版本号:
- dataVersion: 节点数据版本号
- cversion: 子节点版本号
- aclVersion: 节点访问控制列表版本号
所有的写操作都会使相应的版本号增加。写操作必须指定要更新的ZNode的版本号,版本号不一致会导致写入失败。
Zxid
所有对Zookeeper状态的改变都会产生一个Zxid(ZooKeeper Transaction Id),Zxid全局有序。
Zxid为标识事件发生的先后顺序: 即事件A发生早于事件B,那么事件A的Zxid定小于事件B的Zxid。
每个ZNode维护两个Zxid:
- cZxid: Znode创建
- mZxid: Znode最近修改
Zxid是一个64位的数字, 高32位表示Zookeeper集群leader, 低32位表示逻辑顺序。每次leader改变后, 新产生的Zxid高32位都会改变。
节点类型
Zookeeper中的节点分为两种:
- 临时节点: 临时节点依赖于创建节点的会话(Session), 一旦Session结束临时节点会被自动删除。临时节点不允许拥有子节点
- 永久节点: 永久节点生存期不依赖于客户端会话,只有客户端执行删除操作时才会删除。
Zookeeper 可以创建顺序子节点,即创建子节点时在路径结尾添加一个自增的32位 id, 该id在该节点的父节点下是唯一的。
Watch
Zookeeper 所有的读操作getData(), getChildren()和 exists()都可以设置 Watch 触发器。
Watch 触发器是一次性的,当触发器通知了一次状态变化后消失,不会通知状态的再次变化。
Zookeeper 与客户端之间通过 Tcp Socket 进行通信, Zookeeper 会主动将时间通知客户端。
Zookeeper 保证客户端只有首先收到了Watch通知后,才会感知到它所设置监视的znode发生了变化。
Zookeeper 支持三种类型的watch:
- exists: 被监视的Znode 创建、删除、数据改变时被触发
- getData: 被监视的Znode 删除、数据改变时被触发
- getChildren: 被监视的Znode 删除、创建子节点、删除子节点时被触发
Zookeeper 应用
ZooKeeper 是具有较高一致性的分布式协调服务,它提供以下保证:
- 原子性: 所有操作具有原子性
- 分布式一致性: 从任意节点中读取到的数据都是一致的
- 顺序一致性: 从一个客户端来的更新请求会被顺序执行; 写操作是全局有序的;
- 持久性: 写操作一旦成功,直到被覆盖为止持续有效
Zookeeper 使用数据副本和崩溃恢复机制保证数据安全和集群高可用性。
Zookeeper 使用基于 Paxos 算法的 ZAB协议(Zookeeper Atomic Broadcast)进行写操作,保证集群数据的一致性。
配置中心
我们可以将系统中通用配置信息写入 ZNode 中,客户端启动时从 Zookeeper 获取配置数据并监视配置节点的变化,当配置发生改变 Zookeeper 会通知所有的客户端获取最新数据,从而实现在线更新配置。
适合使用Zookeeper维护的配置通常:
- 数据量较小
- 在运行时动态发生变化
- 各客户端读取到数据需要相同
- 具有顺序一致性,客户端只要读取到新版本的数据,此后就不能读取到旧版本数据
当服务启动时,服务提供者可以在Zookeeper的相应路径下创建临时节点,并在节点中写入服务配置信息。服务关闭(崩溃)时,临时节点自动删除。
客户端启动时从 ZooKeeper 读取服务提供者信息从而实现自动的服务发布/移除功能。
分布式锁
Zookeeper 的临时节点可以维护客户端持有锁的状态,加锁失败的客户端可以使用 Watch 机制监视锁的释放情况,实现阻塞等待加锁。
Zookeeper 的顺序节点可以实现一个简单的队列,可以利用此特性实现公平锁。客户端在锁节点下创建顺序子节点,持有最小子节点的客户端成功加锁,加锁失败的客户端 Watch 前一个顺序子节点,从而实现先到先得的公平锁机制。
命名服务
ZooKeeper 的顺序节点可以生成全局唯一ID, 我们可以利用该ID为服务命名。相对于UUID, 该名称较短且可以保证绝不重复。
Master选举
与分布式公平锁应用类似,ZooKeeper 可以维护集群 Master。
集群中所有可以成为 Master 的进程都在 Zookeeper 中的指定路径下创建顺序子节点,持有最小子节点的进程成为Master。
集群中所有进程都 Watch 指定路径下节点的情况,一旦发生变化则重新读取最小子节点的持有者作为Master。
脑裂问题
传统集群实现方案是运行一个备用Master节点,备用Master节点定期向主Master节点发送ping请求,若能及时收到主Master的ack响应则认为正常。
若Ack响应超时,备用Master则会取代原主Master成为新的集群主Master节点。

若响应超时因为主Master故障导致,备用Master成为新的主节点完全正常。
若超时因为主备 Master 节点间 ping-ack 网络故障导致,那么主Master工作正常,而备用Master却误认为主Master崩溃而进行取代,那么集群中可能出现多个Master共存的故障(即脑裂故障)。
若使用 Zookeeper 维护 Master 信息,无论是因为主Master故障还是通信问题导致最小子节点被删除,备用Master持有的节点都会成为最小子节点。
此时,所有客户端都会受到通知并得知 Master 变更,保证集群中只有一个 Master。
当崩溃的Master恢复后,它将成为新的备用Master加入集群。
ZooKeeper 无法避免通信故障导致误判 Master 状态,但是可以保证在任何情况下集群中只有一个 Master 节点。
ZooKeeper概念与应用的更多相关文章
- ZooKeeper概念
这可能是把ZooKeeper概念讲的最清楚的一篇文章 相信大家对 ZooKeeper 应该不算陌生,但是你真的了解 ZooKeeper 是什么吗?如果别人/面试官让你讲讲 ZooKeeper 是什么, ...
- 这可能是把ZooKeeper概念讲的最清楚的一篇文章
我本人曾经使用过 ZooKeeper 作为 Dubbo 的注册中心,另外在搭建 Solr 集群的时候,我使用到了 ZooKeeper 作为 Solr 集群的管理工具. 前几天,总结项目经验的时候,我突 ...
- ZooKeeper原理 --------这可能是把ZooKeeper概念讲的最清楚的一篇文章
相信大家对 ZooKeeper 应该不算陌生,但是你真的了解 ZooKeeper 是什么吗?如果别人/面试官让你讲讲 ZooKeeper 是什么,你能回答到哪个地步呢? 我本人曾经使用过 ZooKee ...
- zookeeper概念与原理
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等. 1 Zookeeper的基本概念 1.1 角色 ...
- 可能是把 ZooKeeper 概念讲的最清楚的一篇文章
转载自:https://github.com/Snailclimb/JavaGuide/blob/master/%E4%B8%BB%E6%B5%81%E6%A1%86%E6%9E%B6/ZooKeep ...
- Zookeeper 概念
Zookeeper: Zookeeper是一个高可用的分布式管理与协调框架,基于ZAB算法(原子消息广播协议)的实现.该框架能够很好的保证分布式环境中数据的一致性.也只是基于这样的特性,使得Zooke ...
- 8.1.Zookeeper概念简介
1.分布式系统概述 理解1: 分布式系统:分布式系统是针对一个大系统而言,将一个大系统分成多个子系统,即多个工程系统. 我们先看下传统的系统模式: 传统的系统模式将多个功能模块全部在一个工程中写 ...
- Zookeeper与Kafka基础概念和原理
1.zookeeper概念介绍 在介绍ZooKeeper之前,先来介绍一下分布式协调技术,所谓分布式协调技术主要是用来解决分布式环境当中多个进程之间的同步控制,让他们有序的去访问某种共享资源,防止造成 ...
- zookeeper基本概念及原理
zookeeper是一个分布式的,开源的分布式应用程序,该程序主要用于管理其他分布式应用程序.其他分布式应用程序可以基于zookeeper实现数据同步,配置维护和命名服务等等.zookeeper是Ha ...
随机推荐
- 【轻松前端之旅】CSS盒子模型
盒子模型,也叫框模型,在CSS里是很重要的概念. 每个元素都可以看做一个盒子.盒子包含四个部分:外边距(margin).边框(border).内边距(padding).元素内容(element con ...
- C++标准库第二版笔记 2
C++标准库第二版笔记 2 微小但重要的语法提升 template表达式内的空格: vector< list<int> >; // OK in each C++ version ...
- # 2019-2020-3 《Java 程序设计》第五周学习总结
2019-2020-3 <Java 程序设计>第五周知识总结 1.使用interface来定义一个接口.接口定义同类的定义类似,也是分为接口的声明和接口体,其中接口体由常量定义和方法定义两 ...
- git cmd 命令在已有的仓库重新添加新的文件夹
正确步骤: 1. git init //初始化仓库 git add .(文件name) //添加文件到本地仓库 git commit -m “first commit” //添加文件描述信息 git ...
- Python自动化开发 - 堡垒机实例
本节内容 一.堡垒机介绍 1. SSHClient 2. SFTPClient 3. Transport 二.堡垒机实现 一.堡垒机介绍 1. SSHClient 用户连接远程服务器并执行基本命令 1 ...
- 我知道的nginx配置
1.nginx配置文件 2.配置访问域名 #京淘商品管理系统 server { listen 80; server_name manage.jt.com; location / { proxy_pas ...
- Python自动化编程-树莓派GPIO编程(二)
树莓派我们编程一般都直接用高效的python,针对于GPIO编程,python也是有这一方面的库的,这里最有名也是最常用的就是RPI.GPIO了.这个库是专门为树莓派GPIO编程所设计的,利用它你可以 ...
- 深圳scala-meetup-20180902(3)- Using heterogeneous Monads in for-comprehension with Monad Transformer
scala中的Option类型是个很好用的数据结构,用None来替代java的null可以大大降低代码的复杂性,它还是一个更容易解释的状态表达形式,比如在读取数据时我们用Some(Row)来代表读取的 ...
- 解决C#调用执行js报检索 COM 类工厂中 CLSID 为 {0E59F1D5-1FBE-11D0-8FF2-00A0D10038BC} 组件失败
最近做了一个模拟请求的网站简化原网站的繁琐数据,提出有用的数据简单展示并完成post.由于原网站数据有js加密,所以我抓出原网站的js解密方法,由C#调用js得到解密后的数据. 整个抓包的框架是用的苏 ...
- Http Header 之 Requests Header 和 Responses Header
在开发中,经常会遇到对网络请求添加相应的头信息,下面我们梳理一下Http Header相关的内容. 一.Requests Header Header 解释 示例 Accept 指定客户端能够接收的内容 ...