zookeeper我们常用来做分布式协调中间件,很多时候我们都接触不到它的原理和用法,我对他的了解也仅限于知道它可以做分布式协调、配置管理、分布式锁,并且有个watch节点监听常常能听到。接下来我要系统的学下zookeeper的功能和原理,一起走进zookeeper的世界
zookeeper主要目的就是为了分布式应用提供协同服务,zookeeper的节点管理机制,当节点发生变化时(创建、删除、数据变更),可以通知各个客户端,利用这种特性,zk的主要场景就如我前面说的:
1. 统一配置:把配置放在ZooKeeper的节点中维护,当配置变更时,客户端可以收到变更的通知,并应用最新的配置。
2. 集群管理:集群中的节点,创建ephemeral的节点,一旦断开连接,ephemeral的节点会消失,其它的集群机器可以收到消息。
3. 分布式锁:多个客户端发起节点创建操作,只有一个客户端创建成功,从而获得锁。
参考 https://blog.51cto.com/nileader/932948
create [-s] [-e] path data acl
ls path [watch]
ls2 path [watch]
[zk: localhost:2181(CONNECTED) 17] ls2 /persistence
[]
cZxid = 0x12
ctime = Tue Mar 26 06:52:28 GMT 2019
mZxid = 0x12
mtime = Tue Mar 26 06:52:28 GMT 2019
pZxid = 0x12
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
[zk: localhost:2181(CONNECTED) 18] ls /persistence
[]
[zk: localhost:2181(CONNECTED) 2] ls / 1
[persistence, temporary, mycat, zookeeper]
[zk: localhost:2181(CONNECTED) 3] create -e /temp 123
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/
Created /temp
[zk: localhost:2181(CONNECTED) 4] create -e /temp2 123
Created /temp2
get path [watch]
[zk: localhost:2181(CONNECTED) 5] get /temp2
123
cZxid = 0x17
ctime = Tue Mar 26 06:59:20 GMT 2019
mZxid = 0x17
mtime = Tue Mar 26 06:59:20 GMT 2019
pZxid = 0x17
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x103c831d4dc0003
dataLength = 3
numChildren = 0
stat path [watch]
set path data [version]
[zk: localhost:2181(CONNECTED) 10] set /temp2 456
cZxid = 0x17
ctime = Tue Mar 26 06:59:20 GMT 2019
mZxid = 0x18
mtime = Tue Mar 26 07:12:27 GMT 2019
pZxid = 0x17
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x103c831d4dc0003
dataLength = 3
numChildren = 0
rmr path
[zk: localhost:2181(CONNECTED) 12] rmr /temp2
[zk: localhost:2181(CONNECTED) 13] get /temp2
Node does not exist: /temp2
delete path [version]
[zk: localhost:2181(CONNECTED) 17] create /per 1
Created /per
[zk: localhost:2181(CONNECTED) 18] create /per/subper 2
Created /per/subper
[zk: localhost:2181(CONNECTED) 19] delete /per
Node not empty: /per
[zk: localhost:2181(CONNECTED) 20] delete /per/subper
[zk: localhost:2181(CONNECTED) 21] delete /per
[zk: localhost:2181(CONNECTED) 22] ls /per
Node does not exist: /per
history
列出最近的10条历史记录[zk: localhost:2181(CONNECTED) 23] history
13 - get /temp2
14 - ls /
15 - ls /temp
16 - get /temp
17 - create /per 1
18 - create /per/subper 2
19 - delete /per
20 - delete /per/subper
21 - delete /per
22 - ls /per
23 - history
redo cmdno
根据 cmdno 重复之前的命令,cmdno 就是方括号里面最后的数字,每次执行命令都会自增。[zk: localhost:2181(CONNECTED) 25] redo 22
Node does not exist: /per
[zk: localhost:2181(CONNECTED) 26] redo 17
Created /per
printwatches on|off
[zk: localhost:2181(CONNECTED) 28] printwatches
printwatches is on
[zk: localhost:2181(CONNECTED) 29] ls /mynode
Node does not exist: /mynode
[zk: localhost:2181(CONNECTED) 30] create /mynode 123
Created /mynode
[zk: localhost:2181(CONNECTED) 31] ls /mynode watch
[]
[zk: localhost:2181(CONNECTED) 34] create /mynode/subnode 234
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/mynode
Created /mynode/subnode
[zk: localhost:2181(CONNECTED) 35] printwatches off
[zk: localhost:2181(CONNECTED) 36] ls /mynode 2
[subnode]
[zk: localhost:2181(CONNECTED) 37] create /mynode/subnode2 567
Created /mynode/subnode2
close
[zk: localhost:2181(CONNECTED) 38] close
2019-03-26 07:26:59,240 [myid:] - INFO [main:ZooKeeper@693] - Session: 0x103c831d4dc0003 closed
[zk: localhost:2181(CLOSED) 39] 2019-03-26 07:26:59,241 [myid:] - INFO [main-EventThread:ClientCnxn$EventThread@522] - EventThread shut down for session: 0x103c831d4dc0003
ls
Not connected
[zk: localhost:2181(CLOSED) 40] ls /
Not connected
connect host:port
[zk: localhost:2181(CLOSED) 42] connect
2019-03-26 07:28:18,093 [myid:] - INFO [main:ZooKeeper@442] - Initiating client connection, connectString=localhost:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@782830e
[zk: localhost:2181(CONNECTING) 43] 2019-03-26 07:28:18,096 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@1029] - Opening socket connection to server localhost/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)
2019-03-26 07:28:18,097 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@879] - Socket connection established to localhost/127.0.0.1:2181, initiating session
2019-03-26 07:28:18,100 [myid:] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@1303] - Session establishment complete on server localhost/127.0.0.1:2181, sessionid = 0x103c831d4dc0004, negotiated timeout = 30000
[zk: localhost:2181(CONNECTED) 43] ls /
[mycat, mynode, zookeeper, persistence, per]
quit
直接退出当前的 zkCli 命令行。sync path
ACL 权限 | ACL 简写 | 允许的操作 |
---|---|---|
CREATE | c | 创建子节点 |
READ | r | 获取节点的数据和它的子节点 |
WRITE | w | 设置节点的数据 |
DELETE | d | 删除子节点 (仅下一级节点) |
ADMIN | a | 设置 ACL 权限 |
命令 | 语法 | 描述 |
---|---|---|
getAcl | getAcl path | 读取ACL权限 |
setAcl | setAcl path acl | 设置ACL权限 |
addauth | addauth scheme auth | 添加认证用户 |
create | create [-s] [-e] path data acl | 创建节点时指明 ACL 权限 |
方案 | 描述 |
---|---|
world | 只有一个用户:anyone,代表所有人(默认) |
ip | 使用IP地址认证 |
auth | 使用已添加认证的用户认证 |
digest | 使用“用户名:密码”方式认证 |
setAcl <path> world:anyone:<acl>
[zk: localhost:2181(CONNECTED) 7] getAcl /world
'world,'anyone
: cdrwa
[zk: localhost:2181(CONNECTED) 8] setAcl /world world:anyone:cdr
cZxid = 0x27
ctime = Tue Mar 26 07:41:43 GMT 2019
mZxid = 0x27
mtime = Tue Mar 26 07:41:43 GMT 2019
pZxid = 0x27
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 1
numChildren = 0
[zk: localhost:2181(CONNECTED) 9] set /world 234
Authentication is not valid : /world
setAcl <path> ip:<ip>:<acl>
[zk: localhost:2181(CONNECTED) 10] create /ip hello
Created /ip
[zk: localhost:2181(CONNECTED) 11] getAcl /ip
'world,'anyone
: cdrwa
[zk: localhost:2181(CONNECTED) 12] setAcl /ip ip:52.231.163.100:cdrwa
cZxid = 0x2a
ctime = Tue Mar 26 07:56:21 GMT 2019
mZxid = 0x2a
mtime = Tue Mar 26 07:56:21 GMT 2019
pZxid = 0x2a
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
[zk: localhost:2181(CONNECTED) 13] getAcl /ip
'ip,'52.231.163.100
: cdrwa
[zk: localhost:2181(CONNECTED) 14] get /ip
Authentication is not valid : /ip
addauth digest <user>:<password> #添加认证用户
setAcl <path> auth:<user>:<acl>
[zk: localhost:2181(CONNECTED) 15] create /auth hello
Created /auth
[zk: localhost:2181(CONNECTED) 16] addauth digest admin:tom
[zk: localhost:2181(CONNECTED) 17] setAcl /auth auth:tom:cdrwa
cZxid = 0x2c
ctime = Tue Mar 26 08:04:23 GMT 2019
mZxid = 0x2c
mtime = Tue Mar 26 08:04:23 GMT 2019
pZxid = 0x2c
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
[zk: localhost:2181(CONNECTED) 18] getAcl /auth
'digest,'admin:cFk4QI8k/ZVgHVEnb06Vtoc651o=
: cdrwa
断开以后再连上,需要重新认证
WatchedEvent state:SyncConnected type:None path:null
[zk: localhost:2181(CONNECTED) 0] get /auth
Authentication is not valid : /auth
setAcl <path> digest:<user>:<password>:<acl>
[root@izbp1itlw36onyj4m9b4hiz ~]# echo -n admin:123456 | openssl dgst -binary -sha1 | openssl base64
0uek/hZ/V9fgiM35b0Z2226acMQ=
[zk: localhost:2181(CONNECTED) 21] create /digest hello
Created /digest
[zk: localhost:2181(CONNECTED) 22] setAcl /digest digest:admin:0uek/hZ/V9fgiM35b0Z2226acMQ=:cdrw
cZxid = 0x39
ctime = Tue Mar 26 08:22:04 GMT 2019
mZxid = 0x39
mtime = Tue Mar 26 08:22:04 GMT 2019
pZxid = 0x39
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
[zk: localhost:2181(CONNECTED) 23] getAcl /digest
'digest,'admin:0uek/hZ/V9fgiM35b0Z2226acMQ=
: cdrw
[zk: localhost:2181(CONNECTED) 24] get /digest
Authentication is not valid : /digest
[zk: localhost:2181(CONNECTED) 25] addauth digest admin:123456
[zk: localhost:2181(CONNECTED) 26] get /digest
hello
cZxid = 0x39
ctime = Tue Mar 26 08:22:04 GMT 2019
mZxid = 0x39
mtime = Tue Mar 26 08:22:04 GMT 2019
pZxid = 0x39
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
[zk: localhost:2181(CONNECTED) 27] addauth digest admin:tim
[zk: localhost:2181(CONNECTED) 28] create /createnode hello auth:tim:cdrwa
Created /createnode
[zk: localhost:2181(CONNECTED) 29] getAcl
[zk: localhost:2181(CONNECTED) 30] getAcl /createnode
'digest,'admin:0uek/hZ/V9fgiM35b0Z2226acMQ=
: cdrwa
'digest,'admin:H4JbicQawMpoqvA2LI0LFNFSMNE=
: cdrwa
[zk: localhost:2181(CONNECTED) 31] get /createnode
hello
cZxid = 0x3b
ctime = Tue Mar 26 08:27:27 GMT 2019
mZxid = 0x3b
mtime = Tue Mar 26 08:27:27 GMT 2019
pZxid = 0x3b
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
[zk: localhost:2181(CONNECTED) 32] close
[zk: localhost:2181(CLOSED) 33] connect
[zk: localhost:2181(CONNECTED) 34] get /createnode
Authentication is not valid : /createnode
[zk: localhost:2181(CONNECTED) 35] getAcl /createnode
'digest,'admin:0uek/hZ/V9fgiM35b0Z2226acMQ=
: cdrwa
'digest,'admin:H4JbicQawMpoqvA2LI0LFNFSMNE=
: cdrwa
[zk: localhost:2181(CONNECTED) 36] addauth digest admin:tim
[zk: localhost:2181(CONNECTED) 37] get /createnode
hello
cZxid = 0x3b
ctime = Tue Mar 26 08:27:27 GMT 2019
mZxid = 0x3b
mtime = Tue Mar 26 08:27:27 GMT 2019
pZxid = 0x3b
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
listquota path
、setquota -n|-b val path
、delquota [-n|-b] path
[zk: localhost:2181(CONNECTED) 10] ls /zookeeper/quota
[]
[zk: localhost:2181(CONNECTED) 11] get /zookeeper/quota
cZxid = 0x0
ctime = Thu Jan 01 00:00:00 GMT 1970
mZxid = 0x0
mtime = Thu Jan 01 00:00:00 GMT 1970
pZxid = 0x0
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 0
[zk: localhost:2181(CONNECTED) 12] listquota /persistence
absolute path is /zookeeper/quota/persistence/zookeeper_limits
quota for /persistence does not exist.
[zk: localhost:2181(CONNECTED) 13] setquota -n 3 /persistence
Comment: the parts are option -n val 3 path /persistence
[zk: localhost:2181(CONNECTED) 14] create /persistence/node1 123
Created /persistence/node1
[zk: localhost:2181(CONNECTED) 15] create /persistence/node2 124
Created /persistence/node2
[zk: localhost:2181(CONNECTED) 16] create /persistence/node3 125
Created /persistence/node3
[zk: localhost:2181(CONNECTED) 17] listquota /persistence
absolute path is /zookeeper/quota/persistence/zookeeper_limits
Output quota for /persistence count=3,bytes=-1
Output stat for /persistence count=4,bytes=12
[zk: localhost:2181(CONNECTED) 18] delquota -n /persistence
[zk: localhost:2181(CONNECTED) 19] listquota /persistence
absolute path is /zookeeper/quota/persistence/zookeeper_limits
Output quota for /persistence count=-1,bytes=-1
Output stat for /persistence count=4,bytes=12
public void process(WatchedEvent event)
public void processResult(int rc, String path, Object ctx, List<String> children)
@Override
public Set<Watcher> materialize(Watcher.Event.KeeperState state,
Watcher.Event.EventType type,
String clientPath)
{
Set<Watcher> result = new HashSet<Watcher>();
switch (type) {
case None://初始化连接时进入
result.add(defaultWatcher);//defaultWatcher如果填空,后续会报错
private void processEvent(Object event) {
try {
if (event instanceof WatcherSetEventPair) {
// each watcher will process the event
WatcherSetEventPair pair = (WatcherSetEventPair) event;
for (Watcher watcher : pair.watchers) {
try {
watcher.process(pair.event);//watcher为null
zk.create("/mypath", new byte[0],
ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT);
zkc.create().withMode(CreateMode.PERSISTENT).forPath("/mypath", new byte[0]);
在ZK集群中,Leader的作用是保证变更操作(create\setData\delete)的顺序性。 它将接收到的请求转换成事务,然后提议followers按照顺序应用这些事务。在初始阶段,所有的ZK服务端都处于LOOKING状态,要么找到已经存在Leader结点,要么自己选举出Leader。成为Leader的节点将进入LEADING状态,其它则将进入FOLLOWING状态。
细节:
192.168.0.1:2181/app/X
protected int electionAlg = 3;
case 3: qcm = createCnxnManager(); QuorumCnxManager.Listener listener = qcm.listener; if(listener != null){ listener.start(); le = new FastLeaderElection(this, qcm); } else { LOG.error("Null listener when initializing cnx manager"); } break;
参考 https://blog.csdn.net/feixiang2039/article/details/79810102#zookeeper-%E5%91%BD%E4%BB%A4 zookeeper 客户端 zkCli 命令详解 https://github.com/llohellohe/llohellohe.github.com/blob/master/readers/ZooKeeper llohellohe/llohellohe.github.com http://www.cnblogs.com/leesf456/p/6098255.html Zookeeper客户端 https://blog.csdn.net/cxhzqhzq/article/details/6568040 Zookeeper全解析——Paxos作为灵魂 http://blog.chinaunix.net/uid-26726125-id-4038581.html zookeeper跟经典paxos的对比(附源码) https://blog.csdn.net/panxj856856/article/details/80403487 FastLeaderElection选举算法