zookeeper (一) 概述&使用
很多都是翻译的 官网:https://zookeeper.apache.org/
内容
1. 概述
1.1 简介
什么是zookeeper ?
分布式应用程序的分布式协调服务
zookeeper 是分布式应用程序的分布式开源协调服务。它公开了一组简单的原语,分布式应用程序可以基于这些原语实现更高级别的同步、配置维护、组和命名服务。它被设计为易于编程,并使用一种数据模型,该模型以熟悉的文件系统目录树结构为样式;
1.2 数据模型
zookeeper 允许分布式进程通过共享的分层命名空间相互协调;命名空间很像标准文件系统。名称是由斜杠 (/) 分隔的一系列路径元素。zookeeper 命名空间中的每个节点都由路径标识。
每个节点,在 zookeeper 中称为 znodes ;zookeeper 数据保存在内存中,这意味着 zookeeper 可以实现高吞吐量和低延迟数字;
1.3 设计目标
zookeeper 实施非常重视高性能、高可用性、严格有序的访问;可以用于大型分布式系统,不会成为单点故障;
zookeeper 复制:与它协调的分布式进程一样,zookeeper 本身旨在通过一组称为 ensemble 的主机进行复制。节点之间相互通信;维护各个节点的状态
zookeeper 速度很快:但是最好不要把zookeeper作为数据库,它在读取比写入更常见的情况下表现最佳,比率约为 10:1
1.4 数据节点
我们使用术语znode来明确我们正在谈论 zookeeper 数据节点;每个节点存储的数据通常很小,在字节到千字节的范围内 1MB ;Znode 维护一个统计结构,其中包括数据更改、ACL 更改和时间戳的版本号,以允许缓存验证和协调更新;
zookeeper 也有临时节点的概念。只要创建 znode 的会话处于活动状态,这些 znode 就存在。当会话结束时,znode 被删除。
注:Session的SessionTimeout值用来设置一个客户端会话的超时时间。当由于服务器压力太大、网络故障或是客户端主动断开连接等各种原因导致客户端连接断开时,只要在SessionTimeout规定的时间内能够重新连接上集群中任意一台服务器,那么之前创建的会话仍然有效
1.5 集群节点
集群中三个角色 :Leader ,Follower ,Observer
1.5.1 Leader
是zookeeper集群的中心,负责协调集群中的其他节点;只有一个
- 集群的写请求;Follower与Observer节点的写请求都会转交Leader 执行。Leader接受到一个写请求后,首先会发送给所有的Follower,统计Follower写入成功的数量。当有超过半数的Follower写入成功后,Leader就会认为这个写请求提交成功,通知所有的Follower commit这个写操作,保证事后哪怕是集群崩溃恢复或者重启,这个写操作也不会丢失。
- 和Follower ,Observer 保持心跳
- 崩溃恢复时负责恢复数据以及同步数据到Follower ,Observer
1.5.2 Follower
多个
- 和Leader 保持心跳
- Leader挂了,有选举权,( 谦让 一般是拥有最大
myid
的当选) - 写请求转发
- 处理Leader 的请求和消息
1.5.3 Observer
只是提高zookeeper读性能(也就是支持更多的客户端连接)的同时又不影响zookeeper的写性能;当Follower 越多,写性能就越低;
- 同步Leader 数据
- 不参与leader选举,没有投票权。也不参与写操作的提议过程
- 数据不持久化,只存在内存
1.6特性
- 顺序一致性 - 来自客户端的更新将按照它们发送的顺序应用。
- 原子性 - 更新成功或失败。没有部分结果。
- 单一系统映像 - 客户端将看到相同的服务视图,而不管它连接到的服务器如何。即,即使客户端故障转移到具有相同会话的不同服务器,客户端也永远不会看到系统的旧视图。
- 可靠性 - 快速恢复主节点Leader
- 及时性——系统的客户视图保证在一定的时间范围内是最新的。
2. 使用
2.1 zookeeper 原语
上面说的 zookeeper 提供一组简单的原语来完成自己的业务实现;
[zk: localhost:2181(CONNECTED) 7] help
zookeeper -server host:port cmd args
stat path [watch]
set path data [version]
ls path [watch]
delquota [-n|-b] path
ls2 path [watch]
setAcl path acl
setquota -n|-b val path
history
redo cmdno
printwatches on|off
delete path [version] ## 删除一个节点
sync path ## 等待数据传播
listquota path
rmr path ### 移出节点
get path [watch]
create [-s] [-e] path data acl ### [-e] :ephemeral 表示创建临时节点 [-s] 防止并发写入失败
addauth scheme auth
quit
getAcl path
close
connect host:port
2.2 连接
创建了一个会话 sessionid ,集群其他节点会同步这个sessionId ,并消耗一个事务id
[root@localhost bin]# ./zkCli.sh
Connecting to localhost:2181
.........
2022-04-06 22:43:05,594 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$Send
Thread@1235] - Session establishment complete on server localhost/127.0.0.1:2181, sessionid = 0x47ffeb878c00000, negotiated timeout = 30000 ### 创建了一个会话 sessionid ,集群其他节点会同步这个sessionId ,并消耗一个事务id
2.3 创建节点
1.创建永久节点
[zk: localhost:2181(CONNECTED) 12] create /test "test1"
Created /test ### 有响应 创建成功
[zk: localhost:2181(CONNECTED) 14] create /test/test2node '2node'
Created /test/test2node
[zk: localhost:2181(CONNECTED) 15] get /test
"test1"
cZxid = 0xf0000000b ##cZxid create 创建 /test 0x f:纪元 0000000b : 创建的事务id 递增(集群)
ctime = Thu Apr 07 19:56:53 CST 2022
mZxid = 0xf0000000b ##mZxid modify 修改 /test 0x f:纪元 0000000b : 修改的事务id 递增
mtime = Thu Apr 07 19:56:53 CST 2022
pZxid = 0xf0000000c ##pZxid 该节点下创建的最大的节点id 对应下面子节点
[zk: localhost:2181(CONNECTED) 16] get /test/test2node
'2node'
cZxid = 0xf0000000c
ctime = Thu Apr 07 19:57:22 CST 2022
mZxid = 0xf0000000c
mtime = Thu Apr 07 19:57:22 CST 2022
pZxid = 0xf0000000c
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0 ### ephemeral 临时 客户端退出还存在
dataLength = 7
2.创建临时节点
[zk: localhost:2181(CONNECTED) 18] create -e /test/modee 'enode'
Created /test/modee
[zk: localhost:2181(CONNECTED) 19] get /test/modee
'enode'
cZxid = 0xf0000000d
ctime = Thu Apr 07 20:20:14 CST 2022
mZxid = 0xf0000000d
mtime = Thu Apr 07 20:20:14 CST 2022
pZxid = 0xf0000000d
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x47ffeb878c00000 ### 临时节点属于会话 查看上面的sessionId ;是创建会话的时候创建的 sessionId ,会话退出 节点消失,临时节点可以被其他会话看到
dataLength = 7
numChildren = 0
[zk: localhost:2181(CONNECTED) 20]
注意:当客户端连接到zookeeper 节点,节点会创建一个 sessionId,并同步到其他的zookeeper 节点,sessionId 也会保存在客户端,当连接的zookeeper 宕机,转移连接到其他的zookeeper 节点
2.4 并发创建节点
防止节点下名字重复 -s
[zk: localhost:2181(CONNECTED) 26] create -s /test/node8 'node8'
Created /test/node80000000006
##另一个节点
[zk: localhost:2181(CONNECTED) 17] create -s /test/node8 'node8'
Created /test/node80000000007