![0803d0eb4b827be81ac0df380117671c.png](https://i-blog.csdnimg.cn/blog_migrate/5e28d0e1ead525da7a85d7c7e1548606.jpeg)
Zookeeper
Zookeeper是chubby 的开源实现,保证分布式一致性的特性。
chubby 是 google 的,完全实现 paxos 算法,不开源。zookeeper 是 chubby的开源实现,使用 zab 协议,paxos 算法的变种。
特点
1. 顺序一致性
2. 原子性
3. 单一视图
4. 可靠性
5. 实时性(最终一致性)
使用场景
- 数据的发布订阅:一般包含两种模式推(Push)拉(Pull)。
实现全局配置通常具备3个特性
1. 数据量小
2. 数据内容运行时动态变化
3. 集群中各机器共享,配置一致
- 负载均衡
基于zookeeper实现动态DNS方案
- 命名服务
是分布式最基本的公共服务,被命名的实体通常是集群中的机器,提供服务的地址。
- 分布式协调/通知
特有watcher注册与异步通知机制,能够很好的实现分布式环境下不同系统之间的通知与协调,实现对数据变更的实时处理。
- 集群管理
对机器在线率有较高要求的场景,户端在节点上注册一个Watcher,当发生变化时,通知客户端
- 分布式锁
这个主要得益于ZooKeeper为我们保证了数据的强一致性。
- 分布式队列
通过在节点上创建临时顺序节点,获取最小的值,保证了FIFO特性。
羊群效应
Zookeeper的watch机制会造成羊群效应。当一个节点修改时,造成所有其他节点同时通知唤醒,一般只需注册监听自己的前一个节点的状态即可。
Znode数据节点类型
(1)PERSISTENT-持久节点
(2)EPHEMERAL-临时节点
(3)PERSISTENT_SEQUENTIAL-持久顺序节点
(4)EPHEMERAL_SEQUENTIAL-临时顺序节点
常见问题
集群支持动态添加机器吗?
其实就是水平扩容了,Zookeeper 在这方面不太好。两种方式:
- 全部重启:关闭所有 Zookeeper 服务,修改配置之后启动。不影响之前客户端的会话。
- 逐个重启:在过半存活即可用的原则下,一台机器重启不影响整个集群对外提供服务。这是比较常用的方式。
Zookeeper 对节点的 watch 监听通知是永久的吗?为什么不是永久的?
不是。官方声明:一个 Watch 事件是一个一次性的触发器,当被设置了 Watch的数据发生了改变的时候,则服务器将这个改变发送给设置了 Watch 的客户端,以便通知它们。
zookeeper 是如何保证事务的顺序一致性的?
zookeeper 采用了全局递增的事务 Id 来标识,所有的 proposal(提议)都在被提出的时候加上了 zxid,zxid 实际上是一个 64 位的数字,高 32 位是 epoch( 时期; 纪元; 世; 新时代)用来标识 leader 周期,如果有新的 leader 产生出来,epoch会自增,低 32 位用来递增计数。当新产生 proposal 的时候,会依据数据库的两阶段过程,首先会向其他的 server 发出事务执行请求,如果超过半数的机器都能执行并且能够成功,那么就会开始执行。
使用Zookeeper
(单机模式)
1.将conf下的zoo_sample.cfg重命名为zoo.cfg
#修改配置文件
clientPort=2181
dataDir=/var/lib/zookeeper/
#server.myid=ip:2888:3888
2.执行bin目录下`sh zkServer.sh start`启动服务
3.`telnet 127.0.0.1 2181`验证服务器是否启动成功。然后输入`stat`查看启动信息。
cZxid创建事务ID mZxid更新节点事务ID mtime最后更新时间 ZNode数据版本
(集群模式)
1.将conf下的zoo_sample.cfg重命名为zoo.cfg
#修改配置文件
clientPort=2181
dataDir=$(ZK_HOME)/data/
#server.myid=ip:2888:3888
server.1=ip:2888:3888
server.2=ip:2888:3888
server.3=ip:2888:3888
2.创建data文件夹,创建myid文件,取值范围1~255
在dataDir下创建myid文件,保存一个数字。myid作为不同机器的唯一标识。
3.执行bin目录下`sh zkServer.sh start`启动服务
4.`telnet 127.0.0.1 2181`验证服务器是否启动成功。然后输入`stat`查看启动信息。
stat查看信息单机模式是:standalone 集群模式是:leader。
bin目录下的可执行脚本
- zkCleanup.sh:清理zookeeper历史数据,包括事务日志和快照数据文件。
- zkCli.sh:客户端
- zkEnv.sh:设置环境变量
- zkServer.sh:服务启动、停止和重启脚本
#启动
sh zkServer.sh start
#停止
sh zkServer.sh stop
#查看状态
sh zkServer.sh status
#连接本机服务器
sh zkCli.sh
#连接指定服务器
sh zkCli.sh -server ip:port
常用命令
#创建节点 create [-s] [-e] path data acl( -s 顺序 -e 临时 acl 权限控制)
create /test qaz
#列出路径 ls path
ls /
#获取节点数据内容和属性 get path
get /test
#更新数据 set path data
set /test wsx
#删除 delete path 删除一个节点需要该节点下没有子节点
delete /test
部分配置说明
clientPort:服务器对外暴露的端口。
dataDir:配置zookeeper存储快照文件的目录。
dataLogDir:事务日志的存储目录,默认路径为dataDir。
tickTime:最小时间单元,很多设置时间以此为单位,默认值3000ms。
initLimit:tickTime的10倍,Leader等待Follower启动并完成数据同步的时间。
syncLimit:tickTime的5倍,心跳检测的最大时延。
snapCount:两次快照之间的事务操作次数。默认值100000。
preAllocSize:事务日志文件分配的磁盘空间,默认值65536KB,即64M。
minSessionTimeout/maxSessionTimeout:tickTime的2到20倍,会话的超时时间。
maxClientCnxns:单台连接并发数,默认60。
jute.maxbuffer:单数据节点Znode的最大数据量,默认1048575字节。
server.id=host:port:port:集群配置,第一个端口通讯与数据同步,第二个端口用于选举。
四字命令
telnet后输入stat。查看服务器运行时状态 mntr详细统计信息
telnet后输入conf。查看服务器配置信息
telnet后输入cons。查看所有客户端的连接信息
telnet后输入crst。重置客户端的连接统计信息
telnet后输入srst。重置服务器的连接统计信息
telnet后输入envi。查看服务器环境信息
telnet后输入ruok。查看服务器是否运行(are your ok?)
telnet后输入wchs。查看服务器的Watcher的概要信息
telnet后输入wchc。查看服务器的Watcher的详细信息
开启远程JMX
在%ZK_HOME%/bin目录下的zkServer.sh文件中ZOOMAIN后添加
-Dcom.sun.management.jmxremote.port=21811
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
再通过JConsole(内置基于JMX的图形化管理工具)进行Zookeeper的JMX管理
单点与容灾
单点通过集群部署解决。zookeeper集群不是一定要奇数台机器才能不是,只是根据选举过半原则,奇数和偶数台允许宕机的服务器数一样。故一般选取奇数台服务器搭建集群。
容灾可同步多机房部署,双机房不能很好的实现容灾
三机房部署
n1=(s-1)/2
n2=1 ~(s-n1)/2
n3=s-n1-n2