ZooKeeper
简介
-
ZooKeeper是一个开源的分布式协调服务,重视高性能、高可用、严格有序的访问
-
Zookeeper中利用被称为znode的节点保存数据,数据将保存在内存(ram)中,最多存储1MB
-
由于旨在协调数据,因此znode存储的数据很小,通常为状态信息、位置信息、配置信息等
-
znodes的组织结构类似于标准文件目录系统结构
特点
- zk集群中的每个服务都是可复制的,所以每个服务都了解彼此,并维护单一状态
- zk服务用数字标记每次数据更新来反映zk事务的顺序
- zk集群必须部署奇数个服务
为什么要部署成奇数?
涉及关键词:集群脑裂问题、过半机制、paxos协议
Zookeeper集群"脑裂"问题 - 运维总结 - 散尽浮华 - 博客园 (cnblogs.com)
选举机制
每一个服务都需要在 data
目录创建一个存放节点id的文本文件(内容只能是一个1~255的数字),文件名为 myid
- myid大的优先选为leader,选出leader后(启动数达到总服务数的半数以上),后面启动的都是follower
- leader挂掉会重选,按以下权重:EPOCH(任期)>ZXID(事务)>SID(服务)
下载
- 将下载的 zookeeper-x.x.xx.tar.gz 复制到
/opt
解压 - 在
/etc/profile
配置文件中添加环境变量,并使用source
命令使新环境变量生效
export ZOOKEEPER_HOME=/opt/zookeeper-3.4.12
export PATH=$PATH:$ZOOKEEPER_HOME/bin
- 进入 zookeeper 根路径的
/conf
目录,修改zoo_sample.cfg
文件为zoo.cfg
# The number of milliseconds of each tick 端与端通信心跳时间,单位ms
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. 注意这里需要自行指定zk数据的存储路径
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
- 为每一个服务创建两个目录:
data
和log
详细安装配置过程可参考
《深入理解Kafka:核心设计与实践原理》第1.2节
《Java高并发核心编程. 卷1, NIO、Netty、Redis、ZooKeeper》第13.1节
常用命令
- 启动服务:
bin/zkServer.sh start
- 停止服务:
bin/zkServer.sh stop
- 查看所有命令:
help
- 查看状态:
bin/zkServer.sh status
- 查看节点:
ls /
- 创建节点:
create /newnode "description"
- 获取节点信息:
get -s /newnode
- 删除节点:
delete /newnode
节点类型
- 持久(Persistent):客户端和服务端断开连接,节点不删除
create /pnode "持久节点"
- 持久顺序(Persistent_Sequential):自动为节点添加数字后缀,维护节点的先后顺序
- 临时(Ephemeral):客户端和服务端断开连接,节点自动删除
create -e /enode "临时节点"
- 临时顺序(Ephemeral_Sequential):自动为节点添加数字后缀,维护节点的先后顺序
分布式锁
- 用创建临时顺序节点表示客户端来抢分布式锁,判定创建后的节点顺序为最小时表示获取到锁
- 如果当前节点抢到锁,则开始处理业务流程,完成后删除自己的对应子节点,通知后一节点
- 如果当前节点未抢占到锁,则监听前一个节点的变化,收到通知后再次判断是否顺序为最小