zookeeper 集群搭建
zookeeper 集群搭建
1. zookeeper简介
zookeeper(简称zk)是一种内存数据库。跟Redis不同,zk的目标并非提是供大量数据存储的容器,而是提供分布式协调服务。主要场景包括命名服务、配置管理、分布式锁、选举等。其实,zk就是树 + watch机制,玩出了各种花样。Zk网上资源丰富,请自行度娘(如果个子高且腿长的可以考虑谷歌)。
2. zookeeper基本概念
2.1 节点类型
Zk存储的节点叫做znode,每个znode名称 + 版本号具有唯一性,即zk不允许创建相同节点。Zk节点由节点路径path和节点数据data组成,Zk按树形结构存储znode,操作znode使用路径path结构:/root/xxx/aaa/bbb。Znode类型大体上分为两种:
永久节点:创建之后一直存在,除非显示删除
临时节点:创建后与创建者关联,当创建者与zk断联后,节点删除
其中临时节点下不能再有子节点,也就是临时节点只能创建在路径末梢,如/path/a/b/c,这里只能让节点c来做临时节点。
细分包含永久排序节点,永久非排序节点,临时排序节点,临时非排序节点,永久排序TTL节点等,暂不展开。
后来根据应用场景,社区上希望出现一种新类型节点,这种节点的特性是当其节点下的子节点为空时,它能自动删除。Zk最终实现的方式并非真正新增了一种节点类型,而是在永久节点上做了包装,命名为container类型,用以实现这种能力。Container节点的作用在2.3节中会进行说明。
2.2 连接状态通知
Zk的连接状态采用异步通知方式,它的连接状态主要包含四种:
CONNECTED
RECONNECTED
SUSPENDED
LOST
其中CONNECTED表示首次连接成功,针对每一个zk连接实例,生命周期中仅会收到一次CONNECTED。
RECONNECTED表示再次连接成功,每次重连成功都会收获此事件。
SUSPENDED表示连接超时,针对每一个zk连接实例,可以设置两个超时时间,其中一个是连接超时时间,另一个是session超时时间。一般将连接超时时间设置较短,用以及时获取连接失效状态,因为暂短的失联也会导致分布式锁、选举的角色失效或发生变化!通常来说,如果需要精确控制时序的场景,则需要监听并感知连接状态变化,在SUSPENDED时采取必要措施,防止乱序执行或资源竞争。当然精确控制会带来逻辑上的复杂性,所以如果能把锁粒度控制在很小的范围内,以至于锁周期内执行的代码非常少(非常快),甚至可以考虑不需要监听连接变化。
LOST表示session超时,session超时时间通常比suspend超时时间设置的更长,对于客户端来说,SUSPENDED和LOST状态的不同可能意味着重连尝试时间间隔的不同,比如在SUSPENDED时重连会更积极,尝试间隔更短,因为那可能仅仅是一段网络抖动导致的;但LOST之后重连次数会以指数退避的方式进行重试。但对于业务来说,SUSPENDED已经够糟了,LOST也不会使情况更糟。
2.3 角色状态通知
Zk角色选举使用临时节点 + watch的机制。在我们控制器分布式集群场景中,协议组由主备协议服务组成,选举情况如图:
其中,选举根节点是永久节点类型,每组协议组由组ID标识的中间层组成,这些节点是2.1节中提到的container类型节点,每个组ID节点下由对应协议节点进行选举,这些协议节点是由临时排序节点类型构成的。当进行选举时,主备协议在组ID节点下尝试创建临时排序节点,这些临时排序节点会按先后顺序排列,由顺序序号决定主备信息。上图是选举逻辑图,实际选举时在zk查询到的节点分布情况如下:
其中/cnp/election-root是选举根节点;/cnp/election-root/1是组ID,表示此协议组ID是1;/cnp/election-root/1下的两个节点,即_c_b79f26c8-b93b-4fcb-ab74-ad65d868989e-latch-0000000001和_c_fa54751f-916a-44d7-83d9-c084eae00b18-latch-0000000000就是临时排序节点构成的选举节点。尾数的0000和0001就是临时节点的序号,选举时由小数值的的节点当选为主,即0000节点为主节点,0001节点所在的client会监听0000节点状态,当0001节点所在的client收到节点0000的remove消息时,0001会升主。
Zk角色状态变化采用异步通知方式,通知类型分为升主和降备。需要注意的是,选举成为主角色或者从备角色成为主角色时会收到升主通知,但选举成为备角色不会收到降备通知!只有当从主角色跌落神坛变成备时(比如因zk连接抖动导致连接状态变为SUSPENDED时)才会收到降备通知!也就是说,当两个节点通过zk选举时,不会出现我们想要的那种主收到升主通知,备收到降备通知,而是只有主收到升主通知,备什么都不会收到!
另外,通过前面的选举机制介绍可知,协议组内协议节点的ID并不会对选举结果产生任何影响,他们仅仅作为选举节点的值。
2.4 znode状态监听
zk提供对节点监听的机制,分为三种类型:pathChildren、node和tree三种。其中node仅用于监听节点自身变化;pathChildren仅用于监听它的子节点变化,对于节点自身或者孙子节点变化则监听不到;tree比较全面,监听自身及以自身为根节点的所有下层节点的变化,比如孙子节点数据变动等。
2.5 分布式锁
分布式锁机制与选举机制基本相同,都是通过创建临时节点来做状态争抢。在实现细节上,为应对公平锁和非公平锁,通过尝试创建同名临时节点方式实现单节点抢占的非公平锁;通过与上面介绍的选举机制相同的临时排序节点来对争抢行为排序,按序号从小到大依次获取锁资源,这里不再详细展开。
3. 集群搭建
3.1 搭建配置
Zookeeper官方下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/
tar -zxvf zookeeper-3.4.6.tar.gz -C /usr/mysoft/zookeeper 即解压到指定的路径
复制三份zookeeper分别命名为zookeeper01、zookeeper02、zookeeper03
进入zookeeper01中创建一个data文件夹,用来保存zookeeper数据。再然后在data中创建一个文件,touch myid编辑myid ,在里面写个编号数字1,然后保存退出。这就是zookeeper的1号节点。
接着修改zookeeper中conf目录下的zoo_sample.cfg为zoo.cfg,这里是使用的cp 复制并重名的方式。
[aaa@qq.com zookeeper]# ll
total 4
drwxr-x--- 6 root root 134 Nov 24 11:36 apache-zookeeper-3.5.8-bin
-rwxr----- 1 root root 189 Nov 24 16:27 start-all.sh
drwxr-x--- 8 root root 158 Nov 24 16:04 zookeeper01
drwxr-x--- 8 root root 158 Nov 24 15:26 zookeeper02
drwxr-x--- 8 root root 158 Nov 24 16:30 zookeeper03
# 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/zookeeper/zookeeper01/data
# the port at which the clients will connect
# 注意相应修改 每个zookeeper节点
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.1=11.15.172.151:2881:3881
server.2=11.15.172.151:2882:3882
server.3=11.15.172.151:2883:3883
# 设置一个管理端口号 不设置的话默认的端口好像是8080 容易跟别的服务重
admin.serverPort=6789
启动脚本
# start-all.sh
cd /usr/local/zookeeper/zookeeper01/bin
./zkServer.sh start
cd /usr/local/zookeeper/zookeeper02/bin
./zkServer.sh start
cd /usr/local/zookeeper/zookeeper03/bin
./zkServer.sh start
cd ../..
3.2 常见问题
4. zookeeper 命令练习
4.1 常用命令
推荐阅读