ZooKeeper的一些基础
- 一些协调的原语经常被各个应用间共享,因此构建协调服务的一个基本方法就是使用一系列原语。比如分布式锁构成了一个原语,它包含创建、获得和释放锁。
- 使用这样的设计会有两个弊端:
- 要么能列举全所有原语,要么能不断扩展原语
- 没有使用灵活的方式来实现现有原语
因此,ZooKeeper并没有直接暴露原语,而是暴露了类似文件系统的API。
- ZNode
ZNode是ZK树形结构的一个节点,它可以包含或者不包含数据。
ZK提供了如下API,用于操作ZNode。
1. create path data
2. delete path data
3. exists path
4. getdata path
5. putdata path data
6. getChildren path
ZK客户端通过建立一个Session会话,来连接ZK服务,通过这些API来操作ZNode。
-
ZNode模式
目前ZNode包含持久化模式和临时模式(ephemeral)。ephemeral
模式指的是这个节点在session断了之后就会消失。而持久模式的ZNode则会继续保持。
在master-worker模式下,ephemeral模式可以用于检测master或者worker是否挂掉。 如果使用持久模式的话,由于ZNode一直存在,无法感知到master或者worker是否已经crash。
ephemeral模式的节点也可以被主动删除。 除了持久模式和ephemeral模式外,ZNode还可以是有序的(自动分配自增ID到节点上,比如task-1,task-2,task-3)。
因此ZNode一共有四种形态:
1. 持久
2. 持久有序
3. ephemeral
4. ephemeral有序 -
Watch和Notifications
Watch可以避免每次主动去请求数据是否变化,而是当ZNode变化时,来通知。Watch是个一次性操作,每次收到通知后,必须重新watch, 如果时间比较久或者ZNode更新频繁,在此时间之间,可能会有更新没有被通知到(还没来得急watch)。ZNode的创建、删除和修改都可以被watch到。
遗留问题:ZK是否能得到每次节点通知?
ZK有个保证是,每次通知被送到每个客户端前,ZNode不会发生下一次的变化。因此客户端可以保证看到的变化是顺序一致的。 -
版本号 每个ZNode都会带有一个版本号,每次节点变化,版本号就会变化。以此可以避免并发的更新问题(版本号不正确的更新会失败)。
-
实际操作
启动ZK: ./zkServer.sh start
客户端连接 ./zkCli.sh
退出 :quit
关闭 ./zkServer.sh stop
Session状态和生命周期
- Session状态:
- NOT_CONNECTED
- CONNECTING
- CONNECTED
- CLOSED
创建Session的时候可以设置超时时间t,t意味着如果在t的时间内没有消息,那么这个session就过期。对于客户端而言,如果在1/3t的时间内没有消息, 那么客户端将发送心跳给服务端。在2/3t的时候,客户端开始寻找另个服务端。因此它有1/3t的时间去建立到另个服务端的新的连接。
- ZXID
为保证客户端重连到新的服务端时,不会看到过期的更新,保证至少新服务端上的更新比客户端之前看到的更新要新。 ZK有个全局的事务ID,每次更新操作后,ZXID会自增。如果客户端连在S1上,并且执行了更新操作,那么ZXID将会+1,比如ZXID=2。 当客户端尝试重连到S2时,若S2由于延迟等,导致上面的ZXID 依旧为1的话,客户端将重试连接到S3(ZXID>2)。
ZK 实现Quorums
./zkServer.sh start CONFIG_FILE
CONFIG_FILE中设置启动的端口和名称等,以及其它的相关server。
tickTime=2000
initLimit=10
syncLimit=5
dataDir=./data
clientPort=2181
server.1=127.0.0.1:2222:2223
server.2=127.0.0.1:3333:3334
server.3=127.0.0.1:4444:4445
实现Lock
客户端通过创建ephemeral znode /lock ,只有一个客户端P会成功,则这个P获取锁成功。 其它客户端失败,它可以通过watch /lock,等删除时继续尝试获得锁。
实现master-worker
- master和worker
create -e /master “”
创建ephemeral 的 master和worker的节点,当断掉后,该节点自动消失。 - client
create -s /assign/task- “” 创建id自增的任务节点
stat PATH可以查看节点状态
get PATH查看节点状态和数据