Table of Contents
定位为: Distributed Coordination Service
相当于一个replset, 在每个机器上都保存全量数据
client 只需要连上任何一个节点就可以读写
CAP中, zk是为C和A设计的.
可用性高: 只要集群中大多数server 存活, 则zk集群是ok的
应用广泛: Hbase, Kafka, Spark, Storm
从 2012年11月发布3.4.5之后, 就很少更新了.
zk的名字空间是一棵树, 类似文件系统的file/dir:
/ ├── apps │ ├── message │ │ ├── server0 │ │ ├── server1 │ │ └── server2 │ └── userinfo └── conf
Persistent Node: 永久有效存储, 除非显示删除
create node时, CreateMode可以指定类型:
PERSISTENT PERSISTENT_SEQUENTIAL EPHEMERAL EPHEMERAL_SEQUENTIAL
create delete exists getChildren getData setData getACL setACL sync: waits for data to be propagated
支持 CAS, 基于ZNode的版本号.
可以watch一个znode, 关注如下事件:
watch 的几个特点:
Watch 保证有序.
watch 保存在Server端Session 中, 一个连接断掉重连后, 相关watch还在
最好不要太多个client watch同一个znode, 容易产生惊群
A client will see a watch event for a znode it is watching before seeing the new data that corresponds to that znode.
A successful create() will trigger a data watch for the znode being created and a child watch for the parent znode. A successful delete() will trigger both a data watch and a child watch (since there can be no more children) for a znode being deleted as well as a child watch for the parent znode.
支持4种身份:
world: anyone auth: anyone(登陆) digest: username:password ip: client host IP
Paxos: 每个写请求, Leader节点会要求所有Follower投票, 投票超过n/2+1通过时 才成功, 保证一致性, 但是不是强一致.
Leader: 接受读+写请求.
Follower 接受读, 写请求转发到Leader
read: 连上哪个server就在哪个server操作
write: 转发到Leader, 由Leader 发起投票
Observer表现和常规Follower一样:
常见用法: 在单个机房内组成一个投票集群,外围的机房都会是一个observer集群和投票集群进行数据交互。
1. getdata(“/servers/leader”, true) 2. if successful follow the leader described in the data and exit 3. create(“/servers/leader”, hostname, EPHEMERAL) 4. if success, I'm lead and exit 5. goto step 1
所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。
/distribute_lock 已经预先存在,客户端在它下面创建临时有序节点(这个可以通过节点的属性控制:CreateMode.EPHEMERAL_SEQUENTIAL来指定)。Zk的父节点(/distribute_lock)维持一份sequence,保证子节点创建的时序性,从而也形成了每个客户端的全局时序。
单机模式:
tickTime=2000 dataDir=/tmp/zk clientPort=2181
tickTime:这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。 dataDir:顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。 clientPort:这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
集群模式增加如下配置:
initLimit=5 # 连接到Leader的超时(单位为tickTime) syncLimit=2 # Leader 与 Follower 之间发消息 的超时 (单位为tickTime) server.1=192.168.211.1:2888:3888 # server.2=192.168.211.2:2888:3888 #
dataDir/myid文件: 对应server.1 的 1
1. download ning@ning-mac ~/Downloads/zookeeper-3.4.6$ cp conf/zoo_sample.cfg conf/zoo.cfg ning@ning-mac ~/Downloads/zookeeper-3.4.6$ ./bin/zkServer.sh start JMX enabled by default Using config: /Users/ning/Downloads/zookeeper-3.4.6/bin/../conf/zoo.cfg Starting zookeeper ... STARTED [zk: 127.0.0.1:2181(CONNECTED) 0] ning@ning-mac ~/Downloads/zookeeper-3.4.6$ bin/zkCli.sh Connecting to localhost:2181 [zk: localhost:2181(CONNECTED) 1] help ZooKeeper -server host:port cmd args connect host:port get path [watch] ls path [watch] set path data [version] rmr path delquota [-n|-b] path quit printwatches on|off create [-s] [-e] path data acl stat path [watch] close ls2 path [watch] history listquota path setAcl path acl getAcl path sync path redo cmdno addauth scheme auth delete path [version] setquota -n|-b val path [zk: localhost:2181(CONNECTED) 2] ls / [zookeeper] [zk: localhost:2181(CONNECTED) 3] create /zk_test my_data Created /zk_test [zk: localhost:2181(CONNECTED) 4] ls / [zookeeper, zk_test] [zk: localhost:2181(CONNECTED) 5] ls /z zookeeper zk_test [zk: localhost:2181(CONNECTED) 5] ls /zk_test [] [zk: localhost:2181(CONNECTED) 6] get /zk_test my_data cZxid = 0x6 ctime = Wed Apr 01 16:05:47 CST 2015 mZxid = 0x6 mtime = Wed Apr 01 16:05:47 CST 2015 pZxid = 0x6 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 7 numChildren = 0
dump envi kill reqs ruok are you ok stat srst 重置stat.
适合读多写少的业务
zk 是比redis复杂的系统, server处理的对象除了存储, 还有session, 连接, 投票.
注意:
zk并不是强一致, 而是最终一致 => 有主从延迟.
正确使用watch需要一定经验.