目录
一、Zookeeper是什么?有什么用?
ZooKeeper 是 Apache 软件基金会的一个软件项目,是一个树形目录服务。
Zookeeper翻译过来就是动物管理员,他还是用来管Hadoop(大象)、Hive(蜜蜂)、Pig(小猪)的管理员。简称zk。
Zookeeper是一个分布式的、开源的分布式应用程序的协调服务。
Zookeeper是一个典型的分布式数据一致性的解决方案,分布式应用程序可以基于它实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。
二、Zookeeper的数据模型
zookeeper 提供的名称空间非常类似于标准文件系统,key-value 的形式存储。名称 key 由斜线 / 分割的一系列路径元素,zookeeper 名称空间中的每个节点都是由一个路径标识。
这里的每一个节点都被称为:ZNode,每个节点上都会保存自己的数据和节点信息。节点可以拥有子节点,同时也允许少量(1MB)数据存储在该节点之下。
Znode的状态属性:
cZxid | 创建节点时的事务ID |
ctime | 创建节点时的时间 |
mZxid | 最后修改节点时的事务ID |
mtime | 最后修改节点时的时间 |
pZxid | 表示该节点的子节点列表最后一次修改的事务ID,添加子节点或删除子节点就会影响子节点列表,但是修改子节点的数据内容则不影响该ID(注意,只有子节点列表变更了才会变更pzxid,子节点内容变更不会影响pzxid) |
cversion | 子节点版本号,子节点每次修改版本号加1 |
dataversion | 数据版本号,数据每次修改该版本号加1 |
aclversion | 权限版本号,权限每次修改该版本号加1 |
ephemeralOwner | 创建该临时节点的会话的sessionID。(**如果该节点是持久节点,那么这个属性值为0)** |
dataLength | 该节点的数据长度 |
numChildren | 该节点拥有子节点的数量(只统计直接子节点的数量) |
节点可以分为四大类:
PERSISTENT 持久化节点
EPHEMERAL 临时节点:-e
PERSISTENT_SQQUENTIAL 持久化顺序节点:-s
EPHEMERAL_SEQUENTIAL 临时顺序节点:-es
三、Zookeeper的命令操作
1、服务端的操作
start/stop/status/restart等
2、客户端常用操作
1、ls命令:查看某个路径下目录列表
ls path |
2、ls2 命令:查看某个路径下目录列表,它比 ls 命令列出更多的详细信息
ls2 path |
3、get命令:用于获取节点数据和状态信息
get path [watch]
|
4、stat 命令:用于查看节点状态信息
stat path [watch]
|
5、create 命令:用于创建节点并赋值
create [-s] [-e] path data acl
|
6、set 命令:用于修改节点存储的数据。
set path data [version]
|
7、delete 命令:用于删除某节点(子节点有内容,不能删除)
delete path [version]
|
8、deleteall命令:删除父节点
delete path |
四、节点特性
1、同一级节点 key 名称是唯一的
实例:
$ ls /
$ create /runoob 2
已存在 /runoob 节点,再次创建会提示已经存在。
2、创建节点时,必须要带上全路径
实例:
$ ls /runoob
$ create /runoob/child 0
$ create /runoob/child/ch01 0
3、session 关闭,临时节点清除
实例:
$ ls /runoob
$ create -e /runoob/echild 0
同时终端二查看该节点:
$ ls /runoob
ctrl+c 关闭终端一连接后,查询终端二 /runoob/echild 节点消失。
$ ls /runoob
4、自动创建顺序节点
实例:
$ create -s -e /runoob 0
5、watch 机制,监听节点变化
事件监听机制类似于观察者模式,watch 流程是客户端向服务端某个节点路径上注册一个 watcher,同时客户端也会存储特定的 watcher,当节点数据或子节点发生变化时,服务端通知客户端,客户端进行回调处理。特别注意:监听事件被单次触发后,事件就失效了。
提示:参考常用命令章节 get 命令监听 watch 使用,后面章节将详细介绍 watch 实现原理。
五、Zookeeper JavaAPI操作
zookeeper有原生API、curator、zkclient等多种,不过目前市面上最流行的是curator.
Curator 是 Netflix 公司开源的一套 zookeeper 客户端框架,解决了很多 Zookeeper 客户端非常底层的细节开发工作,包括连接重连、反复注册 Watcher 和 NodeExistsException 异常等。
Curator 包含了几个包:
- curator-framework:对 zookeeper 的底层 api 的一些封装。
- curator-client:提供一些客户端的操作,例如重试策略等。
- curator-recipes:封装了一些高级特性,如:Cache 事件监听、选举、分布式锁、分布式计数器、分布式 Barrier 等。
简单使用示例:
public class CuratorDemo { } |
六、Zookeeper的集群操作
1、集群角色
Leader领导者:1、处理实务请求 2、集群内各服务器的调度者
Follower跟随者:1、处理非事务请求 ,转发事务请求给Leader领导者 2、参与领导选举
Observer观察者:1、处理非事务请求 ,转发事务请求给Leader领导者
2、Leader选举
zookeeper 的 leader 选举存在两个阶段,一个是服务器启动时 leader 选举,另一个是运行过程中 leader 服务器宕机。
首先我们知道几个重要的参数:
- 服务器 ID(Serverid):编号越大在选举算法中权重越大,比如有三台服务器,编号分别为1,2,3,编号越大在选择算法中的权重越大。
- 事务 ID(zxid):值越大说明数据越新,权重越大
- 逻辑时钟(epoch-logicalclock):同一轮投票过程中的逻辑时钟值是相同的,每投完一次值会增加
然后我们要知道对应的选举状态:
- LOOKING: 竞选状态
- FOLLOWING: 随从状态,同步 leader 状态,参与投票
- OBSERVING: 观察状态,同步 leader 状态,不参与投票
- LEADING: 领导者状态
A、服务器启动时的 leader 选举
每个节点启动的时候都 LOOKING 观望状态,接下来就开始进行选举主流程。这里选取三台机器组成的集群为例。第一台服务器 server1启动时,无法进行 leader 选举,当第二台服务器 server2 启动时,两台机器可以相互通信,进入 leader 选举过程。
- (1)每台 server 发出一个投票,由于是初始情况,server1 和 server2 都将自己作为 leader 服务器进行投票,每次投票包含所推举的服务器serverid、zxid、epoch,使用(myid,zxid)表示,此时 server1 投票为(1,0),server2 投票为(2,0),然后将各自投票发送给集群中其他机器。
- (2)接收来自各个服务器的投票。集群中的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票(epoch)、是否来自 LOOKING 状态的服务器。
- (3)分别处理投票。针对每一次投票,服务器都需要将其他服务器的投票和自己的投票进行对比,对比规则如下:
- a. 优先比较 epoch
- b. 检查 zxid,zxid 比较大的服务器优先作为 leader
- c. 如果 zxid 相同,那么就比较 serverid,serverid较大的服务器作为 leader 服务器
- (4)统计投票。每次投票后,服务器统计投票信息,判断是都有过半机器接收到相同的投票信息。server1、server2 都统计出集群中有两台机器接受了(2,0)的投票信息,此时已经选出了 server2 为 leader 节点。
- (5)改变服务器状态。一旦确定了 leader,每个服务器响应更新自己的状态,如果是 follower,那么就变更为 FOLLOWING,如果是 Leader,变更为 LEADING。此时 server3继续启动,直接加入变更自己为 FOLLOWING。
B、运行过程中的 leader 选举
当集群中 leader 服务器出现宕机或者不可用情况时,整个集群无法对外提供服务,进入新一轮的 leader 选举。
- (1)变更状态。leader 挂后,其他非 Oberver服务器将自身服务器状态变更为 LOOKING。
- (2)每个 server 发出一个投票。在运行期间,每个服务器上 zxid 可能不同。
- (3)处理投票。规则同启动过程。
- (4)统计投票。与启动过程相同。
- (5)改变服务器状态。与启动过程相同。
七、Zookeeper的集群搭建
这里不详细讲解Zookeeper集群搭建过程,可以参考:
https://www.runoob.com/w3cnote/zookeeper-linux-cluster.html