温故知新-快速理解zookeeper功能&应用&选举机制
文章目录
- zookeeper简介
- 什么是zookeeper
- zookeeper应用场景
- zookeeper特点
- zookeeper的角色
- zookeeper的数据模型
- zookeeper常用Shell命令
- zookeeper的acl权限控制
- zookeeper事件监听机制
- watcher概念
- watcher架构
- watcher特性![特性](https://img-blog.csdnimg.cn/20200514002632168.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3lhbmcxOTg5MDc=,size_16,color_FFFFFF,t_70)
- watcher接口设计
- 应用
- 一致性协议:zab协议
- zookeeper的leader选举
- zookeeper 在java中访问API
- 你的鼓励也是我创作的动力
- Posted by 微博@Yangsc_o
- 原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0
zookeeper简介
什么是zookeeper
- zooKeeper由雅虎研究院开发, 是Google Chubby的开源实现, 后来托管到Apache, 于2010年11月正式成为Apache的顶级项目。
- 大数据生态系统里的很多组件的命名都是某种动物或者昆虫, 比如hadoop就是, hive就是。 zookeeper即动物园管理者, 顾名思义就是管理大数据生态系统各组件
的管理员, 如下图所示:
zookeeper应用场景
zooKeeper是一个经典的分布式数据一致性解决方案, 致力于为分布式应用提供一个高性能、 高可用, 且具有严格顺序访问控制能力的分布式协调存储服务。
- 维护配置信息
- 分布式锁服务
- 集群管理
- 生成分布式唯一ID
zookeeper特点
- 高性能
zooKeeper将全量数据存储在内存中, 并直接服务于客户端的所有非事务请求, 尤其适用于以读为主的应用场景
- 高可用
zooKeeper一般以集群的方式对外提供服务, 一般3 ~ 5台机器就可以组成一个可用的Zookeeper集群了, 每台机器都会在内存中维护当前的服务器状态, 并且每台机器之间都相
互保持着通信。 只要集群中超过一半的机器都能够正常工作, 那么整个集群就能够正常对外服务
- 严格顺序访问
对于来自客户端的每个更新请求, ZooKeeper都会分配一个全局唯一的递增编号,这个编号反映了所有事务操作的先后顺序
zookeeper的角色
- Leader:
Zookeeper 集群工作的核心事务请求(写操作) 的唯一调度和处理者,保证集群事务处理的顺序性;
集群内部各个服务器的调度者。
对于 create, setData, delete 等有写操作的请求,则需要统一转发给leader 处理, leader 需要决定编号、执行操作,这个过程称为一个事务
- Follower
处理客户端非事务(读操作) 请求,转发事务请求给 Leader;
参与集群 Leader 选举投票
- Observer:
观察者角色,观察 Zookeeper 集群的最新状态变化并将这些状态同步过来,其对于非事务请求可以进行独立处理,对于事务请求,则会转发给 Leader服务器进行处理。
不会参与任何形式的投票只提供非事务服务,通常用于在不影响集群事务处理能力的前提下提升集群的非事务处理能力;
zookeeper的数据模型
- zookeeper的数据节点可以视为树状结构(或者目录) , 树中的各节点被称为znode(即zookeeper node) , 一个znode可以有多个子节点。 zookeeper节点在结构上表现为树状; 使用路径path来定位某个znode;
- znode, 兼具文件和目录两种特点。 既像文件一样维护着数据、 元信息、 ACL(权限控制)、 时间戳等数据结构, 又像目录一样可以作为路径标识的一部分;
节点数据结构
- 一个znode大体上分为3各部分:
- 节点的数据: 即znode data(节点path, 节点data)的关系就像是java map中(key,value)的关系节点的子节点children
- 节点的状态stat: 用来描述当前节点的创建、 修改记录, 包括cZxid、 ctime等
- 节点状态stat的属性
[zk: localhost:2181(CONNECTED) 7] get /ns-1/tenant
cZxid = 0x6a0000000a
ctime = Wed Mar 27 09:56:44 CST 2019
mZxid = 0x6a0000000a
mtime = Wed Mar 27 09:56:44 CST 2019
pZxid = 0x6a0000000e
cversion = 2
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 2
- 属性说明:
cZxid: 数据节点创建时的事务 ID
ctime: 数据节点创建时的时间
mZxid: 数据节点最后一次更新时的事务 ID
mtime: 数据节点最后一次更新时的时间
pZxid: 数据节点的子节点最后一次被修改时的事务 ID
cversion: 子节点的更改次数
dataVersion: 节点数据的更改次数
aclVersion: 节点的 ACL 的更改次数
ephemeralOwner: 如果节点是临时节点, 则表示创建该节点的会话的
SessionID; 如果节点是持久节点, 则该属性值为 0
dataLength: 数据内容的长度
numChildren: 数据节点当前的子节点个数
节点类型
zookeeper中的节点有两种, 分别为临时节点和永久节点。节点的类型在创建时即被确定, 并且不能改变。
- 临时节点: 该节点的生命周期依赖于创建它们的会话。 一旦会话(Session)结束, 临时节点将被自动删除, 当然可以也可以手动删除。 虽然每个临时的Znode都会绑定到一个客户端会话, 但他们对所有的客户端还是可见的。 另外, ZooKeeper的临时节点不允许拥有子节点。
- 持久化节点: 该节点的生命周期不依赖于会话, 并且只有在客户端显示执行删除操作的时候, 他们才能被删除;
zookeeper常用Shell命令
- 新增节点
create [-s] [-e] path data #其中-s 为有序节点, -e 临时节点
- 更新节点
更新节点的命令是 set , 可以直接进行修改eg:set /hadoop “345”
基于版本号进行更改时, 乐观锁机制, 当你传入的数据版本号(dataVersion) 和当前节点的数据版本号不符合时,zookeeper 会拒绝本次修改:eg: set /hadoop “3456” 1
version No is not valid : /hadoop
- 删除节点
delete path [version]
和更新节点数据一样, 也可以传入版本号, 当你传入的数据版本号 (dataVersion)和当前节点的数据版本号不符合时,zookeeper 不会执行删除操作。
要想删除某个节点及其所有后代节点, 可以使用递归删除, 命令为 rmr path
- 查看节点
get path
- 查看节点状态
可以使用 stat 命令查看节点状态, 它的返回值和 get 命令类似, 但不会返回节点数据
- 查看节点列表
查看节点列表有 ls path 和 ls2 path 两个命令, 后者是前者的增强, 不仅可以查看指定路径下的所有节点, 还可以查看当前节点的信息
- 监听器 get path [watch]
使用 get path [watch] 注册的监听器能够在节点内容发生改变的时候, 向客户端发出通知。 需要注意的是 zookeeper 的触发器是一次性的 (One-time trigger), 即触发一次后就会立即失效。
- 监听器stat path [watch]
使用 stat path [watch] 注册的监听器能够在节点状态发生改变的时候, 向客
户端发出通知
- 监听器ls\ls2 path [watch]
使用 ls path [watch] 或 ls2 path [watch] 注册的监听器能够监听该节点下所有子节点的增加和删除操作
zookeeper的acl权限控制
概述
- zookeeper 类似文件系统, client 可以创建节点、 更新节点、 删除节点,可以通过acl控制节点的权限的控制;
- 使用scheme: id: permission 来标识, 主要涵盖 3 个方面:
权限模式(scheme) : 授权的策略
授权对象(id) : 授权的对象
权限(permission) : 授予的权限 - 其特性如下
- zooKeeper的权限控制是基于每个znode节点的, 需要对每个节点设置权限
- 每个znode支持设置多种权限控制方案和多个权限
- 子节点不会继承父节点的权限, 客户端无权访问某节点, 但可能可以访问它的子节点
权限模式
- world 只有一个用户: anyone, 代表登录zokeeper所有人(默认)
- ip 对客户端使用IP地址认证
- auth 使用已添加认证的用户认证
- digest 使用“用户名:密码”方式认证
授权的对象
- 给谁授予权限
- 授权对象ID是指, 权限赋予的实体, 例如: IP 地址或用户。
授予的权限
- create、delete、read、writer、 admin,即 增、 删、 改、 查、 管理权限,这5种权限简写为cdrwa;
注意:这5种权限中, delete是指对子节点的删除权限, 其它4种权限指对自身节点的操作权限 - 授权的相关命令
- getAcl getAcl 读取ACL权限
- setAcl setAcl 设置ACL权限
- addauth addauth 添加认证用户
zookeeper事件监听机制
watcher概念
- zookeeper提供了数据的发布/订阅功能,多个订阅者可同时监听某一特定主题对
象,当该主题对象的自身状态发生变化时(例如节点内容改变、节点下的子节点列表改变等),会实时、主动通知所有订阅者
- zookeeper采用了Watcher机制实现数据的发布/订阅功能。该机制在被订阅对
象发生变化时会异步通知客户端,因此客户端不必在Watcher注册后轮询阻塞,从而减轻了客户端压力。
- watcher机制实际上与观察者模式类似,也可看作是一种观察者模式在分布式场
景下的实现方式。
watcher架构
Watcher实现由三个部分组成:
- Zookeeper服务端
- Zookeeper客户端
- 客户端的ZKWatchManager对象
客户端首先将Watcher注册到服务端,同时将Watcher对象保存到客户端的Watch管
理器中。当ZooKeeper服务端监听的数据状态发生变化时,服务端会主动通知客户端,接着客户端的Watch管理器会触发相关Watcher来回调相应处理逻辑,从而完成整体的数据发布/订阅流程
watcher特性
watcher接口设计
Watcher是一个接口,任何实现了Watcher接口的类就是一个新的Watcher。Watcher内部包含了两个枚举类:KeeperState、EventType
- Watcher通知状态(KeeperState)
KeeperState是客户端与服务端连接状态发生变化时对应的通知类型。路径为
org.apache.zookeeper.Watcher.Event.KeeperState,是一个枚举类,其枚举属性
如下:
- Watcher事件类型(EventType)
EventType是数据节点(znode)发生变化时对应的通知类型。EventType变化时
KeeperState永远处于SyncConnected通知状态下;当KeeperState发生变化时,
EventType永远为None。其路径为org.apache.zookeeper.Watcher.Event.EventType,
是一个枚举类,枚举属性如下:
注:客户端接收到的相关事件通知中只包含状态及类型等信息,不包括节点变化前后的具体内容,变化前的数据需业务自身存储,变化后的数据需调用get等方法重新获取;
应用
了解完zk的基本特性,据此分析一下具体的使用场景案例
配置中心
eg: 数据库用户名和密码信息放在一个配置文件中,应用读取该配置文件,配置文件信息放入缓存。若数据库的用户名和密码改变时候,还需要重新加载缓存,比较麻烦,通过ZooKeeper可以轻松完成,当数据库发生变化时自动完成缓存同步。
设计思路:
- 连接zookeeper服务器
- 读取zookeeper中的配置信息,注册watcher监听器,存入本地变量
- 当zookeeper中的配置信息发生变化时,通过watcher的回调方法捕获数据变化事件
- 重新获取配置信息
生成分布式唯一ID
在单库单表型系统中,通常可以使用数据库字段自带的auto_increment属性来自动为每条记录生成一个唯一的ID。但是分库分表后,就无法在依靠数据库的auto_increment属性来唯一标识一条记录了。可以用zookeeper在分布式环境下生成全局唯一ID。
设计思路:
- 连接zookeeper服务器
- 指定路径生成临时有序节点
- 取序列号及为分布式环境下的唯一ID
注:生产环境,一般采用别的方式:例如雪花算法等
分布式锁
分布式锁有多种实现方式,比如通过数据库、redis都可实现。作为分布式协同
工具ZooKeeper,当然也有着标准的实现方式。下面介绍在zookeeper中如何实现排他锁。
设计思路:
- 每个客户端往/Locks下创建临时有序节点/Locks/Lock 000000001
- 客户端取得/Locks下子节点,并进行排序,判断排在最前面的是否为自己,如果自己的锁节点在第一位,代表获取锁成功
- 如果自己的锁节点不在第一位,则监听自己前一位的锁节点。例如,自己锁节点
Lock 000000001 - 当前一位锁节点(Lock 000000002)的逻辑
- 监听客户端重新执行第2步逻辑,判断自己是否获得了锁
一致性协议:zab协议
- zab协议 的全称是 Zookeeper Atomic Broadcast (zookeeper原子广播)。
- zookeeper 是通过 zab协议来保证分布式事务的最终一致性基于zab协议,zookeeper集群中的角色主要有以下三类,如下表所示:
- zab广播模式工作原理,通过类似两阶段提交协议的方式解决数据一致性:
- leader从客户端收到一个写请求
- leader生成一个新的事务并为这个事务生成一个唯一的ZXID
- leader将这个事务提议(propose)发送给所有的follows节点
- follower节点将收到的事务请求加入到历史队列(history queue)中,并发送ack leader
- 当leader收到大多数follower(半数以上节点)的ack消息,leader会发送commit请求
- 当follower收到commit请求时,从历史队列中将事务请求commit
zookeeper的leader选举
服务器状态
- looking:寻找leader状态。当服务器处于该状态时,它会认为当前集群中没有
leader,因此需要进入leader选举状态。 - leading: 领导者状态。表明当前服务器角色是leader。
- following: 跟随者状态。表明当前服务器角色是follower。
- observing:观察者状态。表明当前服务器角色是observer
服务器启动时期的leader选举
在集群初始化阶段,当有一台服务器server1启动时,其单独无法进行和完成
leader选举,当第二台服务器server2启动时,此时两台机器可以相互通信,每台机器都试图找到leader,于是进入leader选举过程。选举过程如下:
- 每个server发出一个投票。由于是初始情况,server1和server2都会将自己作为
leader服务器来进行投票,每次投票会包含所推举的服务器的myid和zxid,使用(myid, zxid)来表示,此时server1的投票为(1, 0),server2的投票为(2, 0),然后各自将这个投票发给集群中其他机器。- 集群中的每台服务器接收来自集群中各个服务器的投票。
- 处理投票。针对每一个投票,服务器都需要将别人的投票和自己的投票进行pk,pk规则如下优先检查zxid。zxid比较大的服务器优先作为leader。如果zxid相同,那么就比较myid。myid较大的服务器作为leader服务器。对于Server1而言,它的投票是(1, 0),接收Server2的投票为(2, 0),首先会比较两者的zxid,均为0,再比较myid,此时server2的myid最大,于是更新自己的投票为(2, 0),然后重新投票,对于server2而言,其无须更新自己的投票,只是再次向集群中所有机器发出上一次投票信息即可。
- 统计投票。每次投票后,服务器都会统计投票信息,判断是否已经有过半机器接受到相同的投票信息,对于server1、server2而言,都统计出集群中已经有两台机器接受了(2, 0)的投票信息,此时便认为已经选出了leader
- 改变服务器状态。一旦确定了leader,每个服务器就会更新自己的状态,如果是follower,那么就变更为following,如果是leader,就变更为leading
服务器运行时期的Leader选举
- 在zookeeper运行期间,leader与非leader服务器各司其职,即便当有非leader
服务器宕机或新加入,此时也不会影响leader,但是一旦leader服务器挂了,那么整个集群将暂停对外服务,进入新一轮leader选举,其过程和启动时期的Leader选举过程基本一致。 - 假设正在运行的有server1、server2、server3三台服务器,当前leader是
server2,若某一时刻leader挂了,此时便开始Leader选举。选举过程如下:
- 变更状态。leader挂后,余下的服务器都会将自己的服务器状态变更为looking,然后开始进入leader选举过程。
- 每个server会发出一个投票。在运行期间,每个服务器上的zxid可能不同,此时假定server1的zxid为122,server3的zxid为122,在第一轮投票中,server1和server3都会投自己,产生投票(1, 122),(3, 122),然后各自将投票发送给集群中所有机器。
- 接收来自各个服务器的投票。与启动时过程相同
- 处理投票。与启动时过程相同,此时,server3将会成为leader。
- 统计投票。与启动时过程相同。
- 改变服务器的状态。与启动时过程相同。
observer角色及其配置
observer角色特点:
- 不参与集群的leader选举
- 不参与集群中写数据时的ack反馈
- 为了使用observer角色,在任何想变成observer角色的配置文件中加入如下配
置:peerType=observer- 并在所有server的配置文件中,配置成observer模式的server的那行配置追
加:observer,例如:server.3=192.168.60.130:2289:3389:observer
zookeeper 在java中访问API
1、zookeeper java API
https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper
2、开源客户端curator
https://curator.apache.org/dependency-info.html
你的鼓励也是我创作的动力
温故知新-快速理解zookeeper功能&应用&选举机制的更多相关文章
- 简单理解Zookeeper的Leader选举【转】
Leader选举是保证分布式数据一致性的关键所在.Leader选举分为Zookeeper集群初始化启动时选举和Zookeeper集群运行期间Leader重新选举两种情况.在讲解Leader选举前先了解 ...
- 简单理解Zookeeper的Leader选举
Leader选举是保证分布式数据一致性的关键所在.Leader选举分为Zookeeper集群初始化启动时选举和Zookeeper集群运行期间Leader重新选举两种情况.在讲解Leader选举前先了解 ...
- 面试官:说一说Zookeeper中Leader选举机制
哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 今天又是一个阳光明媚的一天,我又 ...
- Zookeeper中的选举机制
Zookeeper虽然在配置文件中并没有指定master和slave,但是,zookeeper工作时,是有一个节点为leader,其他则为follower.leader是通过内部的选举机制临时产生的. ...
- 8.8.ZooKeeper 原理和选举机制
1.ZooKeeper原理 Zookeeper虽然在配置文件中并没有指定master和slave但是,zookeeper工作时,是有一个节点为leader,其他则为follower,Leader是通 ...
- zookeeper 半数可用/选举机制
1.半数可用机制,半数可用指的是zk集群中一半以上的机器正常时集群才能正常工作 已经启动了hadoop002(follower),hadoop003(leader) 下面停止hadoop002 在ha ...
- 温故知新-快速理解Linux网络I/O
文章目录 摘要 阻塞.非阻塞.同步.异步 Linux下的I/O模型 阻塞I/O模型 非阻塞I/O模型 I/O复用模型 select poll epoll 信号驱动I/O模型 异步I/O 参考 你的鼓励 ...
- zookeeper的leader选举机制个人总结
第一步:每个服务器都首先投自己,格式为<sid,zxid>: 第二步:然后将自己的投票以<sid,zxid>形式发送给其他服务器,这样每个服务器除了自己的投票,还有集群中除了自 ...
- 理解zookeeper选举机制
*:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...
随机推荐
- GraphQL-- 使用Apollo Server搭建Node服务端
一.关于Apollo Server Apollo Server是一种使用JS创建GraphQL服务端的一个方案.它的兼容性比较好,可以很好地和GraphQL客户端进行兼容.同时它可以 独立作为服务端进 ...
- 走进WebApiClientCore的设计
WebApiClient WebApiClient是NCC开源社区的一个项目,是目前微服务里http接口调用的一把锋利尖刀,项目早期设计与开发的时候,是基于.netframework的,然后慢慢加入n ...
- Django之forms.ModelForm
通常在Django项目中,我们编写的大部分都是与Django 的模型紧密映射的表单. 举个例子,你也许会有个Book 模型,并且你还想创建一个form表单用来添加和编辑书籍信息到这个模型中. 在这种情 ...
- zabbix 自定义指标数据来源
1.cpu load https://blog.csdn.net/scugxl/article/details/77199403 1)基本含义:运行队列长度,表示当前有多少个正在等待的进程和正在执行的 ...
- Oracle分页查询语句的写法
分页查询是我们在使用数据库系统时经常要使用到的,下文对Oracle数据库系统中的分页查询语句作了详细的介绍,供您参考. AD:2013云计算架构师峰会精彩课程曝光 Oracle分页查询语句使我们最常用 ...
- blazor wasm访问非本地的restful service
准备工作 blazor wasm正式版发布了!在尝试使用的过程中,发现几个小坑,跟大家分享一下,希望有所帮助. 我是通过keycloak来保护blazor和service的,如何保护service请参 ...
- poj3613 求经过n条边的最短路 ----矩阵玩出新高度 。
For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a relay race usin ...
- SpringBoot2.x快速入门指南(一)
SpringBoot2.x快速入门指南(一) 准备工作 IDE: IntelliJ IDEA 2020.3 Java环境 jdk1.8 在官网快速创建SpringBoot项目 下面开始进入正题: 进入 ...
- Thinkphp5 post提交模糊查询带分页如何保留参数
最近做了一个分页的模糊查询post请求,发现查出来的分页点击下一页导致所有的搜索条件被重置,分页效果就失效了. 以下是网上部分解决办法: 控制器代码 public function index($na ...
- NO.5 CCS运行demo(云端)
我们在demo的README中发现如果程序在云端运行会有很酷的界面而且功能会多一些. 首先我们在CCS开始界面点击Resourse Explorer 然后在浏览器中找到对应的demo 打开GUI界面, ...