Zookeeper搭建方式可以分为单机模式、集群模式、伪集群模式。在集群模式下,节点的个数建议为奇数个,且至少为3个节点。因为Zookeeper的leader选取至少要有半数以上的节点。
Zookeeper的搭建方式
- 单机模式: Zookeeper只运行在一台服务器上,适合测试环境
- 伪集群模式: 在一台物理机上运行多个Zookeeper实例
- 集群模式: Zookeeper运行于一个集群上,适合生产环境
单机模式搭建
要搭建Zookeeper环境,首先要先安装JAVA开发环境。
下载ZooKeeper:
https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/stable/
解压:
tar xzf zookeeper-3.4.12.tar.gz
在conf目录下创建一个配置文件zoo.cfg:
cd zookeeper-3.4.12
[heql@ubuntu zookeeper-3.4.12]$ cp conf/zoo_sample.cfg conf/zoo.cfg
配置文件
配置文件zoo.cfg的内容
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/tmp/zookeeper
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
配置项 | 含义 |
---|---|
tickTime | Zookeeper服务器之间或客户端与服务器之间维持心跳的时间间隔,每隔tickTime时间就会发送一个心跳 |
initLimit | 允许follower连接并同步到Leader的初始化连接时间,以tickTime为单位。当初始化连接时间超过该值,则表示连接失败 |
syncLimit | 表示Leader与follower之间发送消息时,请求和应答时间长度。如果follower在设置时间内不能与leader通信,那么此follower将会被丢弃。 |
dataDir | 存储内存中数据库快照的位置 |
clientPort | Zookeeper的端口号 |
maxClientCnxns | 限制连接到Zookeeper的客户端数量 |
运行:
[heql@ubuntu zookeeper-3.4.12]$ bin/zkServer.sh start
查看运行状态:
[heql@ubuntu zookeeper-3.4.12]$ jps
7309 QuorumPeerMain
7887 Jps
伪集群模式搭建
在一台物理机上运行多个Zookeeper实例,这些Zookeeper实例可以组成伪集群模式。在集群为分布式模式下,必须保证每个zoo.conf的各个端口号不能冲突,除了clientPort不同之外,dataDir也不同。另外,还要在dataDir所对应的目录中创建myid文件来指定对应的Zookeeper服务器实例。
在本机上运行3个Zookeeper实例,它们对应的配置文件分别为zoo_2181.cfg
、zoo_2182.cfg
、zoo_2183.cfg
。
如下为zoo_2181.cfg
配置文件的内容:
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/opt/zookeeper/data_2181
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
server.0=127.0.0.1:2287:3387
server.1=127.0.0.1:2288:3388
server.2=127.0.0.1:2289:3389
server.A=B:C:D
- A:其中A是一个数字,表示这个是服务器的编号,对应不同服务器的myid文件内容
- B:是这个服务器的 ip 地址
- C:Leader选举的端口
- D:Zookeeper服务器之间的通信端口
zoo_2182.cfg
和zoo_2183.cfg
与zoo_2181.cfg
配置文件与上面类似,只是clientPort
、dataDir
不同。
zoo_2182.cfg
的clientPort
、dataDir
为:
dataDir=/opt/zookeeper/data_2182
clientPort=2182
zoo_2183.cfg
的clientPort
、dataDir
为:
dataDir=/opt/zookeeper/data_2183
clientPort=2183
在/opt/zookeeper/
目录下创建data_2181
、data_2182
、data_2183
。在data_2181
目录创建一个data_2181
、data_2182
、data_2183
分别创建一个myid
文件,内容分别为0、1、2。
启动Zookeeper服务:
[heql@ubuntu zookeeper-3.4.12]$ bin/zkServer.sh start conf/zoo_2181.cfg
ZooKeeper JMX enabled by default
Using config: conf/zoo_2181.cfg
Starting zookeeper ... STARTED
[heql@ubuntu zookeeper-3.4.12]$ bin/zkServer.sh start conf/zoo_2182.cfg
ZooKeeper JMX enabled by default
Using config: conf/zoo_2182.cfg
Starting zookeeper ... STARTED
[heql@ubuntu zookeeper-3.4.12]$ bin/zkServer.sh start conf/zoo_2183.cfg
ZooKeeper JMX enabled by default
Using config: conf/zoo_2183.cfg
Starting zookeeper ... STARTED
查看启动结果:
[heql@ubuntu zookeeper-3.4.12]$ jps
3232 QuorumPeerMain
3331 Jps
3300 QuorumPeerMain
3259 QuorumPeerMain
Zookeeper服务的运行状态:
[heql@ubuntu zookeeper-3.4.12]$ bin/zkServer.sh status conf/zoo_2181.cfg
ZooKeeper JMX enabled by default
Using config: conf/zoo_2181.cfg
Mode: follower
[heql@ubuntu zookeeper-3.4.12]$ bin/zkServer.sh status conf/zoo_2182.cfg
ZooKeeper JMX enabled by default
Using config: conf/zoo_2182.cfg
Mode: leader
[heql@ubuntu zookeeper-3.4.12]$ bin/zkServer.sh status conf/zoo_2183.cfg
ZooKeeper JMX enabled by default
Using config: conf/zoo_2183.cfg
Mode: follower
Zookeeper命令操作
启动Zookeeper服务之后,可以使用Zookeeper自带的客户端zkCli.sh
,连接到Zookeeper服务,进行相应的操作。
[heql@ubuntu zookeeper-3.4.12]$ bin/zkCli.sh -server 127.0.0.1:2181
基本操作
连上服务器后,可以执行help
命令,查看Zookeeper支持的命令操作:
[zk: 127.0.0.1:2181(CONNECTED) 1] help
ZooKeeper -server host:port cmd args
stat path [watch]
set path data [version]
ls path [watch]
delquota [-n|-b] path
ls2 path [watch]
setAcl path acl
setquota -n|-b val path
history
redo cmdno
printwatches on|off
delete path [version]
sync path
listquota path
rmr path
get path [watch]
create [-s] [-e] path data acl
addauth scheme auth
quit
getAcl path
close
connect host:port
使用ls命令查看当前Zookeeper节点中所包含的内容:
[zk: 127.0.0.1:2181(CONNECTED) 2] ls / [zookeeper]
创建一个新的Znode节点
app
,数据为test
[zk: 127.0.0.1:2181(CONNECTED) 3] create /app test Created /app [zk: 127.0.0.1:2181(CONNECTED) 4] ls / [app, zookeeper]
使用get命令,查看节点的信息:
[zk: 127.0.0.1:2181(CONNECTED) 5] get /app test cZxid = 0x100000002 ctime = Wed Jun 20 20:15:00 CST 2018 mZxid = 0x100000002 mtime = Wed Jun 20 20:15:00 CST 2018 pZxid = 0x100000002 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 4 numChildren = 0
set命令来可以更新节点的数据:
[zk: 127.0.0.1:2181(CONNECTED) 6] set /app update_test cZxid = 0x100000002 ctime = Wed Jun 20 20:15:00 CST 2018 mZxid = 0x100000003 mtime = Wed Jun 20 20:17:53 CST 2018 pZxid = 0x100000002 cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 11 numChildren = 0 [zk: 127.0.0.1:2181(CONNECTED) 7] get /app update_test cZxid = 0x100000002 ctime = Wed Jun 20 20:15:00 CST 2018 mZxid = 0x100000003 mtime = Wed Jun 20 20:17:53 CST 2018 pZxid = 0x100000002 cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 11 numChildren = 0 [zk: 127.0.0.1:2181(CONNECTED) 8]
删除节点:
[zk: 127.0.0.1:2181(CONNECTED) 8] delete /app [zk: 127.0.0.1:2181(CONNECTED) 9] ls / [zookeeper]
ACL权限控制
Zookeeper的ACL,分为三个维度:scheme、id、permission,通常表示为:scheme:id:permission
,schema代表授权策略,id代表用户,permission代表权限。
scheme
scheme即采取的授权策略,每种授权策略对应不同的权限校验方式。下面是Zookeeper常用的几种scheme:
digest
语法:digest:username:BASE64(SHA1(password)):cdrwa
- digest:是授权方式
- username:BASE64(SHA1(password)):是id部分
- cdrwa:权限部份
用户名+密码授权访问方式,是常用的一种授权策略。id部份是用户名和密码做sha1加密再做BASE64加密后的组合,比如设置一个节点的用户名为heql,密码为123456,则表示方式为:heql:BASE64(SHA1(123456)) ⇒ heql:W+qVWaUSzd7VWFNOpAVhryXr8xI=
。
密码加密需要用到Zookeeper的一个工具类来生成,如下所示:
[heql@ubuntu zookeeper-3.4.12]$ java -Djava.ext.dirs=./lib -cp zookeeper-3.4.12.jar org.apache.zookeeper.server.auth.DigestAuthenticationProvider heql:123456
heql:123456->heql:W+qVWaUSzd7VWFNOpAVhryXr8xI=
下面是演示创建节点,并添加授权信息操作节点的示例:
创建节点:
[zk: 127.0.0.1:2181(CONNECTED) 6] create /node data
Created /node
设置权限:
[zk: 127.0.0.1:2181(CONNECTED) 7] setAcl /node digest:heql:W+qVWaUSzd7VWFNOpAVhryXr8xI=:cdrwa
cZxid = 0x100000008
ctime = Wed Jun 20 20:34:02 CST 2018
mZxid = 0x100000008
mtime = Wed Jun 20 20:34:02 CST 2018
pZxid = 0x100000008
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0
获取节点设置的权限:
[zk: 127.0.0.1:2181(CONNECTED) 8] getAcl /node
'digest,'heql:W+qVWaUSzd7VWFNOpAVhryXr8xI=
: cdrwa
没有授权,创建节点失败:
[zk: 127.0.0.1:2181(CONNECTED) 9] create /node/node_01 data
Authentication is not valid : /node/node_01
添加授权信息,就可以正常操作:
[zk: 127.0.0.1:2181(CONNECTED) 10] addauth digest heql:123456
[zk: 127.0.0.1:2181(CONNECTED) 11] create /node/node_01 data
Created /node/node_01
[zk: 127.0.0.1:2181(CONNECTED) 12] ls /node
[node_01]
ip
基于客户端IP地址校验,限制只允许指定的客户端能操作znode。
比如,设置某个节点只允许IP为192.168.1.100
的客户端能读写该写节点的数据:ip:192.168.1.100:rw
setAcl /node_08 ip:192.168.1.100:rw
world
语法:world:anyone:cdrwa
创建节点默认的scheme,所有人都可以访问。
zk: 127.0.0.1:2181(CONNECTED) 24] create /node_02 data
Created /node_02
[zk: 127.0.0.1:2181(CONNECTED) 25] getAcl /node_02
'world,'anyone
: cdrwa
id
id是验证模式,不同的scheme,id的值也不一样。scheme为digest时,id的值为:username:BASE64(SHA1(password))
,scheme为ip时,id的值为客户端的ip地址。scheme为world时,id的值为anyone。
permission
digest:username:BASE64(SHA1(password)):cdrwa
中的cdrwa
即是permission
- CREATE(r):创建子节点的权限
- DELETE(d):删除节点的权限
- READ(r):读取节点数据的权限
- WRITE(w):修改节点数据的权限
- ADMIN(a):设置子节点权限的权限