下载:https://zookeeper.apache.org/ 建议下载zookeeper 3.4.6稳定版的, 3.5版本的在搭建集群时,会出现服务启动失败的错误。
安装: 解压 即可
安装C 语言 api:
进入./zookeeper/src/c目录
./configure
make
make install
Zookeeper 的配置文件在 conf 目录下,这个目录下有 zoo_sample.cfg 和 log4j.properties,需要将 zoo_sample.cfg 改名为 zoo.cfg,因为 Zookeeper 在启动时会找这个文件作为默认配置文件。下面详细介绍一下,这个配置文件中各个配置项的意义。
tickTime=2000
dataDir= /home/zoo/data
clientPort=2181
当这些配置项配置好后,你现在就可以启动 Zookeeper 了,启动后要检查 Zookeeper 是否已经在服务,可以通过 netstat – ano 命令查看是否有你配置的 clientPort 端口号在监听服务。
集群模式
Zookeeper 不仅可以单机提供服务,同时也支持多机组成集群来提供服务。实际上 Zookeeper 还支持另外一种伪集群的方式,也就是可以在一台物理机上运行多个 Zookeeper 实例,下面将介绍集群模式的安装和配置。
Zookeeper 的集群模式的安装和配置也不是很复杂,所要做的就是增加几个配置项。集群模式除了上面的三个配置项还要增加下面几个配置项:
initLimit=5
syncLimit=2
server.1=192.168.211.1:2888:3888
server.2=192.168.211.2:2888:3888
除了修改 zoo.cfg 配置文件,集群模式下还要配置一个文件 myid,这个文件在 dataDir 目录下,这个文件里面就有一个数据就是 A 的值,Zookeeper 启动时会读取这个文件,拿到里面的数据与 zoo.cfg 里面的配置信息比较从而判断到底是那个 server。
进入/bin目录,使用./zkServer.sh start 启动zookeeper服务。 使用./zkServer.sh stop 停止服务。./zkServer.sh status 查看服务状态 (leader or follower).
进入/bin目录下,使用 ./zkCli.sh –server host:port 登陆服务,例如
./zkCli.sh -server 192.168.1.91:2181,键入任意字符出现以下help命令。
[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]
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) 7] create /test null
Created /test
[zk: localhost:2181(CONNECTED) 8] create -e /test0 null
Created /test0
当会话退出,临时节点将会自动删除,并且临时节点无子节点。
关于ACL的设置和使用在下一节单独介绍。
2.get path [watch]和set path data [version]
get是获取Znode的数据及相关属性,而set是修改此Znode的数据.
3.ls path [watch]
查看Znode的子节点
4.stat path [watch]
查看Znode的属性
5.delete path [version]
删除Znode,前提若有子节点,先删除其子节点
6.addauth scheme auth
认证授权,若某个节点需要认证后才能查看,就需要此命令,具体见下节。
传统的文件系统中,ACL分为两个维度,一个是属组,一个是权限,子目录/文件默认继承父目录的ACL。而在Zookeeper中,node的ACL是没有继承关系的,是独立控制的.
多集群共用zookeeper又涉及一个权限隔离的问题。zookeeper本身提供了ACL机制,表示为scheme:id:permissions,第一个字段表示采用哪一种机制,第二个id表示用户,permissions表示相关权限,如只读,读写,管理等。
scheme: scheme对应于采用哪种方案来进行权限管理,zookeeper实现了一个pluggable的ACL方案,可以通过扩展scheme,来扩展ACL的机制。zookeeper-3.4.4缺省支持下面几种scheme:
world: 它下面只有一个id, 叫anyone, world:anyone代表任何人,zookeeper中对所有人有权限的结点就是属于world:anyone的
auth: 它不需要id, 只要是通过authentication的user都有权限(zookeeper支持通过kerberos (http://www.cnblogs.com/jankie/archive/2011/08/22/2149285.html)来进行authencation, 也支持username/password形式的authentication)
digest: 它对应的id为username:BASE64(SHA1(password)),它需要先通过username:password形式的authentication
ip: 它对应的id为客户机的IP地址,设置的时候可以设置一个ip段,比如ip:192.168.1.0/16, 表示匹配前16个bit的IP段
super: 在这种scheme情况下,对应的id拥有超级权限,可以做任何事情(cdrwa)
另外,zookeeper-3.4.4的代码中还提供了对sasl的支持,不过缺省是没有开启的,需要配置才能启用,具体怎么配置在下文中介绍。
* sasl: sasl的对应的id,是一个通过sasl authentication用户的id,zookeeper-3.4.4中的sasl authentication是通过kerberos来实现的,也就是说用户只有通过了kerberos认证,才能访问它有权限的node.(关于sasl 参考:http://www.wxdl.cn/cloud/zookeeper-sasl.html)
id: id与scheme是紧密相关的,具体的情况在上面介绍scheme的过程都已介绍.
permission: zookeeper目前支持下面一些权限:
权限 |
描述 |
备注 |
CREATE |
有创建子节点的权限 |
|
READ |
有读取节点数据和子节点列表的权限 |
|
WRITE |
有修改节点数据的权限 |
无创建和删除子节点的权限 |
DELETE |
有删除子节点的权限 |
|
ADMIN |
有设置节点权限的权限 |
客户端示例:
Created /test
Created /test/test0000000000
ACL的原理:
ZooKeeper 的权限管理通过Server、Client 两端协调完成:
(1) Server端
一个ZooKeeper 的节点存储两部分内容:数据和状态,状态中包含ACL 信息。创建一个znode 会产生一个ACL 列表,列表中每个ACL 包括:
① 权限perms
② 验证模式scheme
③ 具体内容expression:Ids
例如,当scheme="digest" 时, Ids 为用户名密码, 即"root :J0sTy9BCUKubtK1y8pkbL7qoxSw"。ZooKeeper 提供了如下几种验证模式:
① Digest: Client 端由用户名和密码验证,譬如user:pwd
② Host: Client 端由主机名验证,譬如localhost
③ Ip:Client 端由IP 地址验证,譬如172.2.0.0/24
④ World :固定用户为anyone,为所有Client 端开放权限
(2) 客户端
Client 通过调用addAuthInfo()(java, c为zoo_add_auth)函数设置当前会话的Author信息。Server 收到Client 发送的操作请求(除exists、getAcl 之外),需要进行ACL 验证:对该请求携带的Author 明文信息加密,并与目标节点的ACL 信息进行比较,如果匹配则具有相应的权限,否则请求被Server 拒绝。
Zookeeper维护一个类似文件系统的数据结构:
每个子目录项如 NameService 都被称作为 znode,和文件系统一样,我们能够自由的增加、删除znode,在一个znode下增加、删除子znode,唯一的不同在于znode是可以存储数据的。
有四种类型的znode:
1、PERSISTENT-持久化目录节点
客户端与zookeeper断开连接后,该节点依旧存在
2、 PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点
客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号
3、EPHEMERAL-临时目录节点
客户端与zookeeper断开连接后,该节点被删除
4、EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点
客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号
客户端注册监听它关心的目录节点,当目录节点发生变化(数据改变、被删除、子目录节点增加删除)时,zookeeper会通知客户端。
Zookeeper 的watch函数时一次性触发的,即一 个watch事件将会在数据发生变更时发送给客户端。例如,如果客户端执行操作getData(“/znode1″, true),而后 /znode1 发生变更或是删除了,客户端都会得到一个 /znode1 的watch事件。如果 /znode1 再次发生变更,则在客户端没有设置新的watch的情况下,是不会再给这个客户端发送watch事件的。
这就是说,一个事件会发送向客户端,但可能在在操作成功的返回值到达发起变动的客户端之前,这个事件还没有送达watch的客户端。Watch是异步发送 的。但ZooKeeper保证了一个顺序:一个客户端在收到watch事件之前,一定不会看到它设置过watch的值的变动。网络时延和其他因素可能会导 致不同的客户端看到watch和更新返回值的时间不同。但关键点是,每个客户端所看到的每件事都是有顺序的。
注意事项:
使用zookeeper可以进行集群管理,主要针对两点
解决这个问题,可以在约定一个父目录,gropmember,然后再父目录下面,每个机器创建临时节点,并且监听父目录的子节点变化消息,一旦有机器退出集群,对应的子节点也将被删除,其它机器将受到通知。同样,当加入新的机器时,其它机器也将受到通知。
Master的选举与上面的原理大致一致,所有机器创建临时子节点并按顺序编号,每次选择编号最小的子节点对应的机器作为master即可。
另外:
zookeeper
zoo_get(zhandle_t *zh, const char *path, int watch, char *buffer,
int* buffer_len, struct Stat *stat);
1.在传递参数时,buffer_len 的值是buffer缓冲的大小,当zoo_get成功返回后,buffer_len将被至为对应node节点数据的长度
2.如何确定buffer的大小? 可以设置一个大约值,然后当zoo_get 返回后,从stat结构体中获取node数据长度,与返回的buffer_len 进行比较,若是不相符,说明缓冲区小了,这时可以拿到正确的长度,再次get即可。
stat结构体:
struct Stat {
int64_t czxid;
int64_t mzxid;
int64_t ctime;
int64_t mtime;
int32_t version;
int32_t cversion;
int32_t aversion;
int64_t ephemeralOwner;
int32_t dataLength;
int32_t numChildren;
int64_t pzxid;
};