基本概念
集群角色
- Leader
接受所有Follower的提案;
请求并统一协调发起提案;
负责与所有Follower进行内部数据交换(同步)。
Follower
直接为客户端服务;
参与提案的投票;
与Leader交换数据。Observer
直接为客户端服务;
不参与提案的投票;
与Leader交换数据。
数据模型
由znode组成的树形结构,znode是一个跟Unix文件系统路径相似的节点,可以往这个节点存储或获取数据。如下图
版本
- cversion
- dataversion
- aclversion
Acl权限控制
OPEN_ACL_UNSAFE : 对所有用户开放
READ_ACL_UNSAFE : 只读
CREATOR_ALL_ACL: 创建者可以做任何操作
特点
- 顺序一致性:按照客户端发送请求的顺序更新数据。
- 原子性:更新要么成功,要么失败,不会出现部分更新。
- 单一性 :无论客户端连接哪个server,都会看到同一个视图。
- 可靠性:一旦数据更新成功,将一直保持,直到新的更新。
- 及时性:客户端会在一个确定的时间内得到最新的数据。
伪集群环境搭建
- 下载安装包
wget http://mirrors.hust.edu.cn/apache/zookeeper/stable/zookeeper-3.4.9.tar.gz
- 创建三个文件夹,模拟集群
[root@iZwz9io83xn1czh8rty3qlZ zookeeper]# mkdir server1
[root@iZwz9io83xn1czh8rty3qlZ zookeeper]# mkdir server2
[root@iZwz9io83xn1czh8rty3qlZ zookeeper]# mkdir server3
- 分别复制tar包并解压
- 修改server1配置文件
[root@iZwz9io83xn1czh8rty3qlZ conf]# cp zoo_sample.cfg zoo.cfg
[root@iZwz9io83xn1czh8rty3qlZ conf]# vi zoo.cfg
--修改数据存储路径
dataDir=/usr/local/zookeeper/server1/data
--新增集群配置
server.1=xxx.xxx.xxx.xxx:2881:3881
server.2=xxx.xxx.xxx.xxx:2882:3882
server.3=xxx.xxx.xxx.xxx:2883:3883
第一个端口号是leader和follower之间的通信端口;
第二个端口号是选举的端口号;
- 复制到server2、server3
[root@iZwz9io83xn1czh8rty3qlZ conf]# cp zoo.cfg /usr/local/zookeeper/server2/zookeeper-3.4.9/conf/zoo.cfg
[root@iZwz9io83xn1czh8rty3qlZ conf]# cp zoo.cfg /usr/local/zookeeper/server3/zookeeper-3.4.9/conf/zoo.cfg
- 修改dataDir和端口号
--修改对应的端口号,保证不重复
clientPort=2182
--修改对应的路径
dataDir=/usr/local/zookeeper/server2/data
server3同理
- 在对应的data目录下创建myid文件并添加id号,对应着集群配置中的id
[root@iZwz9io83xn1czh8rty3qlZ data]# cd /usr/local/zookeeper/server1/data
[root@iZwz9io83xn1czh8rty3qlZ data]# vi myid
1
:wq
- 服务命令
--服务启动停止等
./zkServer.sh start|stop|status|restart
--客户端连接服务
./zkCli.sh [-timeout 0 -r]-server ip:port
分别启动
- 连接
[root@iZwz9io83xn1czh8rty3qlZ bin]# ./zkCli.sh -server xxx.xxx.xxx.xxx:2182
Connecting to xxx.xxx.xxx.xxx:2182
...
[zk: xxx.xxx.xxx.xxx:2182(CONNECTED) 0]
- 操作命令
- create [-s] [-e] path data acl
//-s 有序
//-e 临时 - ls path [watch] 查看节点目录
- get path [watch]
- set path data [version] 修改节点数据
- delete path [version]
- setquota -n|-b val path 虽然设置了限制,但是仍然是可以创建成功。同时,会bin/zookeeper.out 输出警告信息
7.delquota [-n|-b] path
- create [-s] [-e] path data acl
常见应用场景
配置中心(Configuration Management)
例如,同一个应用系统需要多台Server 运行,它们运行的应用系统的某些配置项是相同的,如果要修改这些相同的配置项,那么就必须同时修改每台运行这个应用系统的Server,这样非常麻烦而且容易出错。
这种情况可以将配置信息交给 Zookeeper 来管理,将配置信息保存在 Zookeeper 的某个目录节点中,然后将所有需要修改的应用机器监控配置信息的状态,一旦配置信息发生变化,每台应用机器就会收到 Zookeeper 的通知,然后从 Zookeeper 获取新的配置信息应用到系统中。
集群管理(Group Membership)
Zookeeper 上创建一个 EPHEMERAL 类型的目录节点,然后每个 Server 在它们创建目录节点的父目录节点上调用 getChildren(String path, boolean watch) 方法并设置 watch 为 true,由于是 EPHEMERAL 目录节点,当创建它的 Server 死去,这个目录节点也随之被删除,所以 Children 将会变化,这时 getChildren上的 Watch 将会被调用,所以其它 Server 就知道已经有某台 Server 死去了。新增 Server 也是同样的原理同理。
统一命名服务(Name Service)
分布式应用中,通常需要有一套完整的命名规则,既能够产生唯一的名称又便于人识别和记住,通常情况下用树形的名称结构是一个理想的选择,树形的名称结构是一个有层次的目录结构,既对人友好又不会重复。
共享锁(Locks)
1、获得锁的Server创建一个 EPHEMERAL_SEQUENTIAL 目录节点,然后调用 getChildren方法获取当前的目录节点列表中最小的目录节点是不是就是自己创建的目录节点,如果正是自己创建的,那么它就获得了这个锁;如果不是那么它就调用exists(String path, boolean watch) 方法并监控 Zookeeper 上目录节点列表的变化,一直到自己创建的节点是列表中最小编号的目录节点,从而获得锁。
2、释放锁只要删除前面它自己所创建的目录节点就行了。
[1] http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/
[2] http://baike.baidu.com/link?url=ShlHMULtsxQ5T-BhYkY_9__v5cZXeEiNiVUmlvnNBAh_Nc0DbhrYp7fqszvMvbyl4lK_g7W_cFFCN2N0glCpNnxVilUQ9dghli_PkRgZc7e