Zookeeper应用场景,安装,常用命令
- Zookeeper介绍
1.1 Zookeeper是做什么的?
Zookeeper由雅虎研究院开发,是Google Chubby的开源实现,后来托管到Apache。
1.2 Zookeeper的应用场景?
1)维护配置信息,作为配置中心
项目中会有一些配置信息,比如数据库的url、user和password等,通常我们会将这些配置放在配置文件中,再将配置文件上传到服务器上。
当配置发生变化时,需要去服务器上修改配置文件。
以前单机版系统还好说,可是如果是个分布式系统,那么需要到很多个服务器上去修改配置信息。这样改很慢不说,也很难保证每台服务器上配置信息的数据一致性。
那么通过zookeeper,发布者可以将数据发布到一个或者一系列节点上,所有的订阅者都可以动态获取数据。
2)分布式锁服务
单机单线程多线程时,发生多个线程数据共享时,一般通过synchronized,lock来解决。
而在分布式环境中,多个机器共享资源,就很难解决数据安全,数据一致的问题。这时zookeeper可以提供分布式锁来解决。
3)集群管理
zookeeper的watcher机制可以监控集群每台机器的运行状态,以事件的方式将机器的状态变化通知到集群,以便集群作出相应的配置调整。
4)生成分布式唯一ID
单机单表单库,可以通过数据库的自增属性,来为数据库中的一条数据生成唯一ID。
但分库分表后,可以用zookeeper在分布式环境下生成全局唯一ID。做法如下:每次要生成一个新ID时,创建一个持久有序节点。
1.3 Zookeeper的设计目标
- 高性能:数据存在内存中
- 高可用:zookeeper一般不会单机部署,而是以集群的方式对外提供数据。只要保证集群中半数以上的机器能够正常工作,那么整个集群就能够正常对外服务。
- 严格顺序访问:对于来自客户端的每一次请求,zookeeper都会分配一个全局唯一的递增编号,保证了所有请求的先后顺序。
- 在MacOS上安装,及启动Zookeeper
2.1. MacOS安装Zookeeper
brew install zookeeper
2.2. 安装好之后,查看zookeeper默认配置文件
$ cd /usr/local/etc/zookeeper
zookeeper $ ls
defaults log4j.properties zoo.cfg zoo_sample.cfg
2.3. 启动zookeeper,启动后查看状态-发现默认standalone单机模式,使用zoo.cfg配置启动。
zoo.cfg默认指定2181为zookeeper对外提供服务的端口。
dataDir指定zookeeper保存数据的目录。
$ zkServer start
ZooKeeper JMX enabled by default
Using config: /usr/local/etc/zookeeper/zoo.cfg
Starting zookeeper ... STARTED
$ zkServer status
ZooKeeper JMX enabled by default
Using config: /usr/local/etc/zookeeper/zoo.cfg
Mode: standalone
#查看zk版本
$ echo stat|nc localhost 2181
Zookeeper version: 3.4.13-2d71af4dbe22557fda74f9a9b4309b15a7487f03, built on 06/29/2018 04:05 GMT
########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=/usr/local/var/run/zookeeper/data
# 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
2.4. 另外,查看zookeeper的bin目录,发现还有个zkCli客户端工具,可以用它来进入zookeeper内部
$ pwd
/usr/local/bin
bin $ ls zk*
zkCleanup zkCli zkServer zkTxnLogToolkit
#到zookeeper内部,并用ls命令查看当前zookeeper中所包含的内容
$ zkCli
Connecting to localhost:2181
Welcome to ZooKeeper!
JLine support is enabled
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper]
[zk: localhost:2181(CONNECTED) 1] ls /zookeeper
[quota]
[zk: localhost:2181(CONNECTED) 2] ls /zookeeper/quota
[]
2.5. 关闭zookeeper
$ zkServer stop
ZooKeeper JMX enabled by default
Using config: /usr/local/etc/zookeeper/zoo.cfg
Stopping zookeeper ... STOPPED
- zookeeper常用命令
help查看所有命令:
[zk: localhost:2181(CONNECTED) 0] 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
3.1 新增节点
create [-s] [-e] path data #其中-s为有序节点,-e为临时节点
#1. 没有加可选项create,创建的是持久化节点。当前回话结束后,这个数据依然会被保留下来。
[zk: localhost:2181(CONNECTED) 3] create /hadoop "123456"
Created /hadoop
#查看此节点的数据
[zk: localhost:2181(CONNECTED) 4] get /hadoop
123456
cZxid = 0xa
ctime = Sat Mar 13 17:50:37 CST 2021
mZxid = 0xa
mtime = Sat Mar 13 17:50:37 CST 2021
pZxid = 0xa
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
#2. 创建持久化有序节点,应用场景:分布式环境下,创建唯一的相应业务ID
[zk: localhost:2181(CONNECTED) 3] create -s /a "a"
Created /a0000000001
[zk: localhost:2181(CONNECTED) 4] get /a0000000001
a
cZxid = 0xd
ctime = Sat Mar 13 17:56:10 CST 2021
mZxid = 0xd
mtime = Sat Mar 13 17:56:10 CST 2021
pZxid = 0xd
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 1
numChildren = 0
#3. 创建临时节点,它的特点是跟当前的临时会话绑定的,退出后数据就不存在了。
zk: localhost:2181(CONNECTED) 5] create -e /tmp "tmp"
Created /tmp
#4. 创建临时有序节点
[zk: localhost:2181(CONNECTED) 2] create -s -e /aa "aa"
Created /aa0000000003
3.2 更新节点
[zk: localhost:2181(CONNECTED) 6] set /hadoop "345"
cZxid = 0xa
ctime = Sat Mar 13 17:50:37 CST 2021
mZxid = 0x12
mtime = Sat Mar 13 18:03:46 CST 2021
pZxid = 0xa
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
#对数据修改的次数记录在 dataVersion 里
#更新数据时,可以将版本号放进set命令里。表示set 数据时,需要匹配版本号
[zk: localhost:2181(CONNECTED) 8] set /hadoop "678" 2
version No is not valid : /hadoop
[zk: localhost:2181(CONNECTED) 9] set /hadoop "678" 1
cZxid = 0xa
ctime = Sat Mar 13 17:50:37 CST 2021
mZxid = 0x14
mtime = Sat Mar 13 18:06:20 CST 2021
pZxid = 0xa
cversion = 0
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
3.3 删除节点
delete path [dataVersion]
[zk: localhost:2181(CONNECTED) 11] delete /aa0000000003 5
version No is not valid : /aa0000000003
[zk: localhost:2181(CONNECTED) 13] delete /aa0000000003
#如果当前节点有子节点,则无法通过delete命令删除当前节点
[zk: localhost:2181(CONNECTED) 15] create /hadoop/node1 "node1"
Created /hadoop/node1
[zk: localhost:2181(CONNECTED) 19] delete /hadoop
Node not empty: /hadoop
#用rmr命令删除当前节点,以及所有子节点
[zk: localhost:2181(CONNECTED) 20] rmr /hadoop
[zk: localhost:2181(CONNECTED) 21] get /hadoop
Node does not exist: /hadoop
3.4 查看节点
[zk: localhost:2181(CONNECTED) 23] get /hadoop
123456
cZxid = 0x1c #数据节点创建时的事务ID
ctime = Sat Mar 13 18:14:08 CST 2021 #数据节点的创建时间
mZxid = 0x1c #数据节点最后一次更新时的事务ID
mtime = Sat Mar 13 18:14:08 CST 2021 #数据节点最后一次更新时间
pZxid = 0x1c #数据节点的子节点最后一次被修改的事务ID
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0 #如果此节点是临时节点,则表示创建该会话的sessionID;如果是持久节点,则该属性值为0
dataLength = 6 #数据的长度
numChildren = 0 #当前节点的子节点个数
3.4 查看节点状态
stat 命令,只返回节点属性,不返回节点数据。而get命令即返回节点属性,也返回数据。
[zk: localhost:2181(CONNECTED) 30] stat /hadoop
cZxid = 0x1c
ctime = Sat Mar 13 18:14:08 CST 2021
mZxid = 0x1c
mtime = Sat Mar 13 18:14:08 CST 2021
pZxid = 0x1c
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
3.5 查看子节点列表
ls 命令返回子节点列表,ls2命令即返回子节点列表,还返回当前节点属性
[zk: localhost:2181(CONNECTED) 31] ls /
[a0000000001, hadoop, zookeeper, tmp1, tmp]
[zk: localhost:2181(CONNECTED) 32] ls /hadoop
[]
[zk: localhost:2181(CONNECTED) 34] ls2 /hadoop
[]
cZxid = 0x1c
ctime = Sat Mar 13 18:14:08 CST 2021
mZxid = 0x1c
mtime = Sat Mar 13 18:14:08 CST 2021
pZxid = 0x1c
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
3.6 监听器
1)get /hadoop watch, get此节点时,添加了一个监听器。后面如果该节点的数据被改变了,会收到通知。
应用场景为,zookeeper作为配置中心使用时,应用程序所依赖的相关配置信息,被放在zookeeper内部。当这些配置信息一旦发生变化,可以通过这种监听机制,来捕获变化,尽快让应用程序读取最新的配置信息。
[zk: localhost:2181(CONNECTED) 35] get /hadoop watch
123456
cZxid = 0x1c
ctime = Sat Mar 13 18:14:08 CST 2021
mZxid = 0x1c
mtime = Sat Mar 13 18:14:08 CST 2021
pZxid = 0x1c
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
#此时,打开另一个会话,修改节点的数据。
#会发现当前会话收到更改通知。
[zk: localhost:2181(CONNECTED) 36]
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/hadoop
2)监听器 stat path watch
使用此命令注册的监听器,能够在节点状态发生变化时,向客户端发出通知
[zk: localhost:2181(CONNECTED) 1] stat /hadoop watch
cZxid = 0x1c
ctime = Sat Mar 13 18:14:08 CST 2021
mZxid = 0x20
mtime = Sat Mar 13 18:29:48 CST 2021
pZxid = 0x1c
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
#此时,打开另一个会话,修改节点的数据。set /hadoop "567"
[zk: localhost:2181(CONNECTED) 2]
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/hadoop
3)监听器ls/ls2 path watch
使用此命令注册的监听器,能够监听该节点下,所有子节点的增加和删除操作。
[zk: localhost:2181(CONNECTED) 6] ls /hadoop
[node2, node1]
[zk: localhost:2181(CONNECTED) 7] ls /hadoop watch
[node2, node1]
[zk: localhost:2181(CONNECTED) 8]
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/hadoop
-
zookeeper的数据模型
zookeeper中的数据节点可以视为树状结构,树中的各个节点被称为znode,一个znode可以有多个子节点。
zookeeper节点的树状结构
可以从三个维度描述一个节点:节点的数据、节点的子节点、节点的相关属性stat
节点的类型:临时节点、永久节点。这些在前面例子中都介绍过。 - zookeeper常用shell命令
5.1 zkServer 启动/停止zk服务
$ zkServer
ZooKeeper JMX enabled by default
Using config: /usr/local/etc/zookeeper/zoo.cfg
Usage: ./zkServer.sh {start|start-foreground|stop|restart|status|upgrade|print-cmd}
#默认使用/usr/local/etc/zookeeper/zoo.cfg
zookeeper $ zkServer stop /usr/local/etc/zookeeper/zoo1.cfg
ZooKeeper JMX enabled by default
Using config: /usr/local/etc/zookeeper/zoo1.cfg
Stopping zookeeper ... STOPPED
5.2 zkCli 客户端连接zk服务
zkCli -server ip:port