一、Zookeeper原理及使用
1.概述
Zookeeper是一个开源的分布式的,为分布式应用提供协调服务的Apache项目。
Zookeeper从设计模式角度来理解,是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生了变化,Zookeeper就负责通知已经在Zookeeper上注册的那些观察者做出相应的反应
Zookeeper = 文件系统 + 通知机制
2.特点
1)Zookeeper:一个领导者(Leader),多个跟随者(Follower)组成的集群。
2)集群中只要有半数以上节点存活,Zookeeper集群就能正常服务。
3)全局数据一制:每个Server保存一份相同的数据副本,Client无论连接到哪个Server,数据都是一致的。
4)更新请求顺序进行,来自同一个Client的更新请求按其发送顺序依次执行。
5)数据更新原子性,一次数据更新要么成功,要么失败。
6)实时性,在一定时间范围内,Client能读到最新数据。
3.数据结构
Zookeeper数据模型的结构与Unix文件系统很类似,整体上可以看作是一棵树,每个节点称作一个ZNode。每一个ZNode默认能够存储1MB的数据,每个ZNode都可以通过其路径唯一标识。
4.应用场景
1)统一命名服务
在分布式环境下,经常需要对应用/服务进行统一命名,便于试别。
例如:IP不容易记住,而域名容易记住。
2)统一配置管理
(1)分布式环境下,配置文件同步非常常见
①一般要求一个集群中,所有的节点的配置信息是一致的,比如Kafka集群。
②对配置文件修改后,希望能够快速同步到各个节点上。
(2)配置管理可交由Zookeeper实现
①可将配置信息写入Zookeeper上的一个ZNode
②各个客户端服务器监听这个ZNode
③一旦ZNode中的数据被修改,Zookeeper将通知各个客户端服务器。
3)统一集群管理
(1)分布式环境中,实时掌握每个节点的状态是必要的。
①可根据节点实时状态做出一些调整
(2)Zookeeper可以实现实时监控节点状态变化
①可将节点信息写入Zookeeper上的一个ZNode。
②监听这个ZNode可获取它的实时状态变化。
4)服务器节点动态上下线
5)软负载均衡
…
二、Zookeeper安装
注意事项:如果不是第一次搭建集群,那么就把zk安装目录下的zkData目录删除,并且把logs目录也删除
1.解压安装
解压Zookeeper安装包到/opt/module/目录下
2.配置服务器编号
1)在/opt/module/zookeeper-3.5.7/这个目录下创建zkData
2)在/opt/module/zookeeper-3.5.7/zkData目录下创建一个myid的文件
3)在文件中添加与server对应的编号
3.配置zoo.cfg文件
1)重命名/opt/module/zookeeper-3.5.7/conf这个目录下的zoo_sample.cfg为zoo.cfg
2)修改zoo.cfg 文件里的数据存储路径配置
①dataDir=/opt/module/zookeeper-3.5.7/zkData
②增加如下配置
server.2=hadoop102:2888:3888
server.3=hadoop103:2888:3888
server.4=hadoop104:2888:3888
③配置参数解读
server.A=B:C:D
A是一个数字,表示这个是第几号服务器
B是这个服务器的地址;
C是这个服务器Follower与集群中的Leader服务器交换信息的端口;
D是万一集群中的Leader服务器挂了,需要一个端口来重新进行选举,选出一个新的Leader,而这个 端口就是用来执行选举时服务器相互通信的端口。
4.分发zk到其他机器
5.在不同机器上修改myid文件中的值
6.自定义群启群停zk服务的脚本
#!/bin/bash
#检验参数
if [ $# -lt 1 ]
then
echo '参数不能为空!!!'
exit
fi
#循环遍历每一台机器,分别启动或者停止ZK服务
for host in hadoop102 hadoop103 hadoop104
do
case $1 in
"start")
echo "*****************start $host zookeeper****************"
ssh $host /opt/module/zookeeper-3.5.7/bin/zkServer.sh $1
;;
"stop")
echo "*****************stop $host zookeeper****************"
ssh $host /opt/module/zookeeper-3.5.7/bin/zkServer.sh $1
;;
"status")
echo "*****************status $host zookeeper****************"
ssh $host /opt/module/zookeeper-3.5.7/bin/zkServer.sh $1
;;
*)
echo '参数有误!!!'
exit
;;
esac
done
三、Zookeeper客户端命令
四、Zookeeper内部原理
1.节点类型
2.stat结构体
(1)czxid-创建节点的事务zxid
每次修改ZooKeeper状态都会收到一个zxid形式的时间戳,也就是ZooKeeper事务ID。
事务ID是ZooKeeper中所有修改总的次序。每个修改都有唯一的zxid,如果zxid1小于zxid2,那么 zxid1在zxid2之前发生。
(2)ctime - znode被创建的毫秒数(从1970年开始)
(3)mzxid - znode最后更新的事务zxid
(4)mtime - znode最后修改的毫秒数(从1970年开始)
(5)pZxid-znode最后更新的子节点zxid
(6)cversion - znode子节点变化号,znode子节点修改次数
(7)dataversion - znode数据变化号
(8)aclVersion - znode访问控制列表的变化号
(9)ephemeralOwner- 如果是临时节点,这个是znode拥有者的session id。如果不是临时节点则是0。
(10)dataLength- znode的数据长度
(11)numChildren - znode子节点数量
3.监听器原理
4.选举机制
1)新搭建集群(没有任何数据)
①. server1启动,此时它会给自己投票,因为当前票数没有过半,当前投票结果
属于(Locking)状态。
②. server2启动,此时先给自己投一票,接下来server2和server1进行通信,互换选票
后发现各自都有一票,最后进行myid的比较 2 > 1,此时server2选举胜出,server1就会
把自己的选票投给server2,最后由于不满足票数过半原则,选举结果继续处于(Locking)
状态。
③. server3启动,先给自己投一票,然后就与server1和server2进行通信,大家互换选票
,因为都是一票,接下来就比较myid ,3 > 2 >1, server3选举胜出,server1和server2
就会把选票投给server3,此时server3就有3张选票,最后满足了票数过半的原则,leader
就选举出来了,就是server3
④.server4启动,由于当前集群中已经选举出了leader,所以server4就自动成为一个follower
⑤.server5启动,由于当前集群中已经选举出了leader,所以server5就自动成为一个follower
注意:当集群没有按照顺时启动的时候,选举结果可生影响,但是选举的过程不变!!
2)集群正在工作中,突然leader宕机,接下来新的leader该如何选出?
– 以上情况出现,会从当前存活的机器中再选出一个leader,此时由于
集群是工作状态,那数据肯定就不为空,zxid就有值,且每台机机器的根节点
zxid 的值也是不一样。这种情况选举的时候就去参考两个条件(myid, zxid)
– 比较原则:zxid 值最大的就被选举为leader,如果在极端情况下,zxid的一样
,此时就会比较 myid。之所以使用zxid作比较,是因为zxid的最大的那台机器
就是我们集群中数据最完整的拿一台机器。
5.写数据流程
er,此时由于
集群是工作状态,那数据肯定就不为空,zxid就有值,且每台机机器的根节点
zxid 的值也是不一样。这种情况选举的时候就去参考两个条件(myid, zxid)
– 比较原则:zxid 值最大的就被选举为leader,如果在极端情况下,zxid的一样
,此时就会比较 myid。之所以使用zxid作比较,是因为zxid的最大的那台机器
就是我们集群中数据最完整的拿一台机器。