zookeeper 简介
Zookeeper是源代码开放的分布式协调服务,是一个高性能的分布式数据一致性的解决方案,它将那些复杂的,容易出错的分布式一致性服务封装起来。用户可以通过调用Zookeeper提供的接口来解决一些分布式应用中的实际问题。
zookeeper 特性
数据一致性
client 不论连接到那个Zookeeper,展示都是同一个试图,即查询的数据都是一样得。这是zookeeper的重要特性。
原子性
要么都更新成功,要么都不更新。即 要么整个集群中所有机器的成功更新某一个事务,要么都不更新。
持久性
一旦zk服务端成功的更新一个事务,并完成对客户端的响应,那么该事务所引起的服务端的状态变更将会一直保留下来,除非有另一个事务又对其进行了改变。
实时性
Zookeeper保证客户端将在非常短的时间间隔范围内获得服务器的更新信息。前提条件是,网络状态良好。
顺序性
如果在一台服务器上消息a在消息b前发布,则所有Server上消息a都在消息b前被发布。底层是通过递增的事务id(zxid)来实现的。
过半性
zookeeper 集群必须有半数以上的机器存活才能正常工作。因为只有满足过半数,才能满足选举机制选出Leader。也只有过半,在做事务决议,事务才能更新。所以一般说zookeeper集群最好是奇数。
zookeeper 特点
zookeeper 结构类似于目录结构,会有一个根节点 / ,每个节点叫 znode 节点,每个znode节点都可以拥有自己的节点
zookpeer的所有操纵,都是基于节点路径来操作的,每个znode节点可以存储数据且名字唯一,多个znode节点形成一个znode树。
znode树是维系在内存中,即znode节点的数据也是存在内存中的,目的是用户快速查询。
Zookepper的使用场景是做分布式协调,多台ZK节点存储的数据是相同的
Zookpper 提供了持久化操作,在 /conf/zoo_sample.cfg 文件中由 dataDir 来决定存储路径
Zookpper 会为每个事务分配一个全局递增事务ID。cZxid(创建节点的事务ID)、mZxid(修改节点的事务ID)、pZxid(此节点的子节点最新的事务ID)
安装
单机
下载
wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.7.0/apache-zookeeper-3.7.0-bin.tar.gz
解压
tar -xvf apache-zookeeper-3.7.0.tar.gz
mv apache-zookeeper-3.7.0 zookeeper-3.7.0
启动
cd /opt/software/zookeeper-3.7.0/conf
cp zoo_sample.cfg zoo.cfg
cd /opt/software/zookeeper-3.7.0/bin
./zkServer.sh start
查看启动成功或进程
jps
启动后回在 bin 目录下生成 zookeeper.out 文件,用于查看报错信息。
集群
zookeeper的集群相对简单,修改方式如下:
- 修改 zoo.cfg
server.1=本机ip:2888:3888
server.2=其他IP1:2888:3888
server.3=其他IP2:2888:3888
1,2,3为zookeeper的集群id,2888原子广播端口,3888选举端口。
- 在 zookeeper 目录下创建 tmp/myid,写下ID号
1
- 把 zookeeper 发送给其他服务器
scp -r /opt/software/zookeeper-3.7.0 root@其他IP:/opt/software/
-
修改其他服务机的 tmp/myid,myid一定是随着 zoo.cfg配置的修改,如其他服务机的IP为 其他IP2,那么他所对因的myid就为以上配置文件3的值。
-
查看是否启动成功 jps
2498 ProdServerStart
- 启动成功在 bin/ 下查看状态
./zkServer.sh status
zookeeper选举机制
一阶段:数据恢复阶段。每台ZK服务器启动时,会从本地数据目录中,找到自己所拥有的最大(最新)的事务ID(Zxid)。
二阶段:每台zk服务器都会提交自己所持有的有效数据进行选举,推荐自己当 Leader,选举数据内容包含如下:
- 自己的最大事务ID(Zxid)
- 自己的选举ID(myid)
- 逻辑的钟值,确保每台ZK服务器在同一轮选择中
- 当前ZK的状态:Looking(处于选举状态)、Follower(处于追随者状态)、Leader(处于领导者状态)、Observer(处于观察者状态)
三阶段:先比较Zxid,谁大谁当Leader,Zxid越大,数据越新。如果Zxid比较不出来,就比较选举myid,谁大谁Leader。PK的原则是要满足过半性,即:1. 选举时要满足过半同意 2. ZK服务器要满足过半存活。所以搭建集群建议为 奇数。
zookeeper集群读写
zookeeper 的读可以从任意节点上去读,但是写的话,必须发给 Leader,由Leader 去发送给所有子节点,写 就使用的是 原子广播性。
如果写的操作发动给 子节点,则子节点会转发给Leader,由Leader做原子广播。
zookeeper集群脑裂
当一个集群出现两个Leader 这种现象称为脑裂,脑裂的危害会使得数据同步过程紊乱。
zookeeper 解决脑裂的机制是选出一个Leader,会为每个Leader分配一个Epoch ID。并且Epoch ID是递增的。所以子节点可以根据Epoch ID数字号,来选择接受最大的Epooch ID的最新数据。
Zxid是由两部分组成,高32位是EpochID,低32位是事务ID。每次新选一个Leader EpochID 会自增,事务ID会从新开始计量。
Observer
zookeeper 的选举模式,决定了zookeeper不能有太多的节点,节点越多性能越差,所以zookeeper引入了 Observer 观察者。
观察者不参与投票,他只监听投票的结果,但客户端可以连接他们并进行读写操作,这些操作都会被转发到Leader,所以我们尽可能的可以多加Observer节点。
observer 的配置如下:
peerType=observer
server.1=IP1:2888:3888
server.2=IP2:2888:3888
server.3=IP3:2888:3888:observer
修改完observer,其他服务器的 zoo.cfg 都要改成
server.1=IP1:2888:3888
server.2=IP2:2888:3888
server.3=IP3:2888:3888:observer
zookeeper常用配置
# 客户端连接端口
clientPort=2181
# 存储快照文件snapshot的目录,默认情况下,事务日志也存在这里
dataDir=/home/tmp/datadir
# 事务输出日志目录
dataLogDir= /home/datalog
# ZK 中所有时间都是以这个时间单元为基础进行整数倍数配置的
# 如 tickTime=2000,则下限 2*tickTime=4000,上限 20*tickTime=40000
# 就是 API在连接 ZK时,如果设置3000,小于ZK下限 2*tickTime,则取4000为数
tickTime=2000
# Follower(子) 启动过程中,会从Leader同步所有数据,然后确定自己能够对外服务的起始状态。
# Leader 允许 Follower在 initLimit 时间内完成这个工作。通常不关心这个参数设置。
# 只有ZK集群数据确实很大,Follower在启动时候,
# 从Leader上同步数据时间边长,则适当调大这个参数。该参数默认:10*tickTime
initLimit=10
# Leader 与 Follower 之间发送消息,请求和应答时间长度。
# 如果 Follower 在设置时间内不能与Leader 进行通信,那么Follower将被丢弃
# 默认时:5*tickTime
syncLimit=5
# session超时时间限制,如果客户端设置的时间不在这个范围,那么会强制设置为最大或最小时间。
# 默认的session超时时间是在 2*tickTime~2=*tickTime 这个范围
# minSessionTimeout=4000
# maxSessionTimeout=40000
# 每进行 snapCount次事务日志输出后,触发一次快照(snapshot),此时,ZK会生成一个 snapshot.* 文件,
# 同时创建一个新得事务日志文件log.*。默认是 100000
# 此外,在产生心Leader时,也会生成新的快照文件,同时会生成对应的事务文件
snapCount=100000
# 3.4.0及之后版本,ZK 提供了自动清理事务日志和快照文件的功能,
# 这个参数指定了清理频率,单位是小时,需要配置一个1或更大的整数,0为不开启自动清理功能。
# purgeInterval 小时清理,snapRetainCount 保留多少个文件不被清理
autopurge.snapRetainCount=3
autopurge.purgeInterval=1
# 控制每个znode节点都可以存储数据的大小,每个节点最大数据量。默认是1M
jute.maxbuffer=1M
# 最大请求堆积数,默认是1000。ZK运行的时候,尽管server已经没有空闲来处理更多的客户端的请求了,
# 但是还是允许客户端请求提交到服务器上来,以提高吞吐性能。
# 当然,为了防止Server内存溢出,这个请求堆积数还是需要限制的。
globalOutstandingLimit=1000
# 预先开辟的磁盘空间,用于后续读写入事务日志。默认是64M,每个事务日志大小就是64M
preAllocSize=64M
# 默认为3,即基于TCP fast paxos election 选举算法。
# ZK 的ZAK写一是类似2PC算法,ZAB算法改进的原型算法是Paxos算法。
# 3.4版本后,1和2对应的选举算法都是UDP,已弃用,所以不需要改该配置。
electionAlg=3
# 默认情况下,Leader 是会接收客户端链接,并提供读写服务。
# 但是,如果你想Leader专注于集群中机器的协调,那么可以将这个参数设置为no,
# 这样一来,会提高整个ZK集群性能。
LeaderServers=no
# 控制每台ZK服务器能处理的客户端并发请求数。
maxClientCnxns=60
zookeeper 常用命令
# 查看当前znode中包含的内容
ls /
# 查看当前节点的详细数据
ls2 /
# 创建两个普通节点
create /sanguo "jinlian"
create /sanguo/shuguo "liubei"
# 获取节点的值
get /sanguo
get /sanguo/shuguo
# 创建短暂性节点
create -e /sanguo/wuguo "zhouyu"
# 退出当前客户端然后再重启客户端
quit
# 创建带序号的节点
create -s /sanguo/weiguo "caocao"
# 修改节点的数据值
set /sanguo/weiguo "caozhi"
# 删除节点
delete ./sanguo/jin
#递归删除节点
rmr /sanguo/weiguo
# 注册监听/sanguo节点的子节点变化,若路径有变化会通知
ls /sanguo watch
# 节点值变化的监听
get /sanguo watch
# 查看节点状态
stat /sanguo
网友评论