环境:CentOS 6.7, java version "1.7.0_51, ZooKeeper 3.4.6
环境:CentOS 6.7, jdk 1.7.0_51, ZooKeeper 3.4.6
(可选)创建新用户
一般我倾向于把需要启动daemon进程,对外提供服务的程序,即服务器类的程序,安装在单独的用户下面。这样可以做到隔离,运维方面,安全性也提高了。
创建一个新的group,
groupadd zookeeper useradd -g zookeeper zookeeper
1. 单机模式(Standalone mode) 单机模式在开发和调试阶段很有用。 1.1 下载,解压 cd /opt ;mkdir app cd app wget http://archive.apache.org/dist/zookeeper/stable/zookeeper-3.4.6.tar.gz tar zxf zookeeper-3.4.6.tar.gz
1.2 启动 默认就是单机模式, $ mv conf/zoo_sample.cfg conf/zoo.cfg $ ./bin/zkServer.sh start
1.3 使用java 客户端连接ZooKeeper $ ./bin/zkCli.sh -server 127.0.0.1:2181 然后就可以使用各种命令了,跟文件操作命令很类似,输入help可以看到所有命令。
1.4 关闭 $ ./bin/zdServer.sh stop
2. 分布式模式(Replicated mode) 在生产环境中,要配置成分布式模式,才能发挥威力。 ZooKeeper集群一般被称为ZooKeeper ensemble,或者 quorum.
2.1 准备3台机器 假设有三台机器,hostname和ip对应关系是: 192.168.10.80 zk01 192.168.10.81 zk02 192.168.10.82 zk03 ZooKeeper不存在明显的master/slave关系,各个节点都是服务器,leader挂了,会立马从follower中 选举一个出来作为leader.由于没有主从关系,也不用配置SSH无密码登录了,各个zk服务器是自己启动 的,互相之间通过TCP端口来交换数据。
2.2 修改配置文件conf/zoo.cfg dataDir=/opt/zookeeper/data dataLogDir=/opt/zookeeper/logs clientPort=2181 tickTime=2000 initLimit=5 syncLimit=2 server.1=zk01:2888:3888 server.2=zk02:2888:3888 server.3=zk03:2888:3888
注: dataDir:数据目录 dataLogDir:日志目录 clientPort:客户端连接端口 tickTime:Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。 initLimit:Zookeeper的Leader 接受客户端(Follower)初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过 5个心跳的 时间(也就是tickTime)长度后 Zookeeper 服务器还没有收到客户端的返回信息,那么表明这个 客户端连接失败。总的时间长度就是 5*2000=10 秒 syncLimit:表示 Leader 与 Follower 之间发送消息时请求和应答时间长度,最长不能超过多少 个tickTime 的时间长度,总的时间长度就是 2*2000=4 秒。 server.A=B:C:D:其中A 是一个数字,表示这个是第几号服务器;B 是这个服务器的 ip 地址; C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来 执行选举时服务器相互通信的端口。如果是伪集群的配置方式,由于 B 都是一样,所以不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。
2.3 myid文件 要在每台机器的dataDir下,新建一个myid文件,里面存放一个数字,用来标识当前主机。 echo "1" >> /opt/zookeeper/data/myid echo "2" >> /opt/zookeeper/data/myid echo "3" >> /opt/zookeeper/data/myid
2.4 启动每台机器 zookeeper-3.4.6/bin/zkServer.sh start zookeeper-3.4.6/bin/zkServer.sh start zookeeper-3.4.6/bin/zkServer.sh start
2.5 查看状态 zookeeper-3.4.6/bin/zkServer.sh status
3.使用java客户端连接ZooKeeper集群 ./bin/zkCli.sh -server zk01:2181 ./bin/zkCli.sh -server zk01:2181 ./bin/zkCli.sh -server zk01:2181
./zkCli.sh -server 127.0.0.1 2181 Connecting to 127.0.0.1 2015-12-03 16:42:31,452 [myid:] - INFO [main:Environment@100] - [zk: 127.0.0.1:2181(CONNECTED) 0] ls / 显示当前数据 [test1, zookeeper]
1) 创建节点 格式:create [-s] [-e] path data acl 其中"-s"表示创建一个"有序"节点,"-e"表示创建一个临时节点.默认为持久性节点 ->create -s /test null ->create /test null 如下为包括ACL的例子: ->create -s /test null digest:test:Kk3Nr5X06NH+XdlGMyOrULgK/mo=:rwcda 创建一个path为"/test"的节点,值为"null",ACL授权方式为"digest",其中授权的用户名:密码为"test:Kk3Nr5X06NH+XdlGMyOrULgK/mo=",ACL的权限列表为"r""w""c""d""a". "digest"授权方式表示client方位此节点数据,需要指定用户名和密码,可以参考zookeeper中 DigestAuthenticationProvider.generateDigest(String ipName)方法;通过向此方法指定原始的用户名和密码即可获得"digest"之后的字符串,比如传入"test:test",将会得 到"test:V28q/NynI4JI3Rk54h0r8O5kMug=",其内部原理是将"密码"部分进行MD5 + sha1操作.再zkCli.sh指令上你需要传递digest之后的字符串. 其中ACL的授权方式有很多种,你可以在ZooDefs类中找到更多的信息. 最后一个参数为权限列表,r表示"read",w表示"write",c表示"create",d表示"delete",a表示"admin" 2) 获取节点数据 格式:get path -> get /test -e cZxid = 0x5b ctime = Mon Sep 16 14:14:06 CST 2013 mZxid = 0x5b mtime = Mon Sep 16 14:14:06 CST 2013 pZxid = 0x67 cversion = 7 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 2 numChildren = 5 你可以从结果列表中,获得所有的节点信息. 3) 查看子节点列表 指令: ls /path 4) 设置节点值 格式: set path data [version] -> set /test 1313131 -1 其中值需要为字符串,版本号可以通过2)中的指令获取,如果版本号为"-1"表示更新时忽略版本校验. 5) 删除所有节点 格式: rmr path -> rmr /test 将会删除"/test"以及其下的所有子节点. 6) 设置ACL 格式: setAcl path acl -> setAcl /test digest:test:Kk3Nr5X06NH+XdlGMyOrULgK/mo=:rwcda 和create指令非常相似. 7) 删除节点 格式: delete path [version] -> delete /test -1 需要注意的是,如果此path下还有子节点,将导致删除失败.这是和"rmr"指令的区别. 8) 添加授权信息 格式: addauth schema auth -> addauth digest test:test 只有授权之后,才能够访问那些具有ACL控制的节点数据.注意"auth"信息为原始的用户名和密码,而不是经过 DigestAuthenticationProvider签名之后的. 如果使用了错误的授权信息,可能导致"Authentication is not valid : ".