作用
分布式系统中的主节点选举! 比如hbase中的老大的产生 Hmaster(HA)
分布式系统中的主从节点感知!
分布式系统中的配置文件同步!
系统服务器的动态上下线感知!!!
分布式系统中的分布式锁的实现!分布式中的同一个对象
分布式系统中的名称服务!
分布式系统中的负载均衡! ...
Zookeeper的功能其实很简单:就是提供协调服务!
协调服务具体来说有三方面:
帮使用者存储一些状态信息
帮使用者读取一些信息
帮使用者监视一些信息的变化,并将变化作为事件通知给使用者
角色
» 领导者(leader),负责进行投票的发起和决议,更新系统状态
» 学习者(learner),包括跟随者(follower)和观察者(observer),follower用于接受客户端请求并想客户端返回结果,在选主过程中参与投票
» Observer可以接受客户端连接,将写请求转发给leader,但observer不参加投票过程,只同步leader的状态,observer的目的是为了扩展系统,提高读取速度
» 客户端(client),请求发起方
Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协
议。Zab协议有两种模式,它们分别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者
崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后
,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。
• 为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。所有的提议(
proposal)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用来标识
leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的
统治时期。低32位用于递增计数。
• 每个Server在工作过程中有三种状态:
LOOKING:当前Server不知道leader是谁,正在搜寻
LEADING:当前Server即为选举出来的leader
FOLLOWING:leader已经选举出来,当前Server与之同步
其他文档:http://www.cnblogs.com/lpshou/archive/2013/06/14/3136738.html
数据存储
Zookeeper维护一个类似文件系统的数据结构:
每个子目录项如 NameService 都被称作为 znode(目录节点),和文件系统一样,我们能够自由的增加、删除znode,在一个znode下增加、删除子znode,唯一的不同在于znode是可以存储数据的。
有四种类型的znode:
PERSISTENT-持久化目录节点
客户端与zookeeper断开连接后,该节点依旧存在
PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点
客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号
EPHEMERAL-临时目录节点
客户端与zookeeper断开连接后,该节点被删除
EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点
客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号
数据读写
» Zookeeper是一个由多个server组成的集群
» 一个leader,多个follower
» 每个server保存一份数据副本
» 全局数据一致
» 分布式读写
» 更新请求转发,由leader实施
Zookeeper 的保证
» 更新请求顺序进行,来自同一个client的更新请求按其发送顺序依次执行
» 数据更新原子性,一次数据更新要么成功,要么失败
» 全局唯一数据视图,client无论连接到哪个server,数据视图都是一致的
» 实时性,在一定事件范围内,client能读到最新数据
Zookeeper节点数据操作流程
注:1.在Client向Follwer发出一个写的请求
2.Follwer把请求发送给Leader
3.Leader接收到以后开始发起投票并通知Follwer进行投票
4.Follwer把投票结果发送给Leader
5.Leader将结果汇总后如果需要写入,则开始写入同时把写入操作通知给Leader,然后commit;
6.Follwer把请求结果返回给Client
Follower主要有四个功能:
• 1. 向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);
• 2 .接收Leader消息并进行处理;
• 3 .接收Client的请求,如果为写请求,发送给Leader进行投票;
• 4 .返回Client结果。
Follower的消息循环处理如下几种来自Leader的消息:
• 1 .PING消息: 心跳消息;
• 2 .PROPOSAL消息:Leader发起的提案,要求Follower投票;
• 3 .COMMIT消息:服务器端最新一次提案的信息;
• 4 .UPTODATE消息:表明同步完成;
• 5 .REVALIDATE消息:根据Leader的REVALIDATE结果,关闭待revalidate的session还是允许其接受消息;
• 6 .SYNC消息:返回SYNC结果到客户端,这个消息最初由客户端发起,用来强制得到最新的更新。
选举机制
Leader选举过程(以3个节点的集群为例):
注:每个节点的配置文件中都有一个自己的独一无二的id
zookeeper的进程在不同的工作模式下,有不同的通信端口(比如选举时,通过端口3888通信;作为leader或者follower接收客户端请求时通过端口2181;leader和follower之间通信用2888)
注意在zk集群安装的时候 会人为的为每台机器分配一个唯一的id
集群初次启动时的选举流程
第一台机器(id=1)启动,发现没有leader,进入投票模式,投自己,并收到自己投这一票,得1票,不能当选leader(当leader的条件是,集群机器数量过半的票数)
第2台机器(id=2)启动,发现没有leader,进入投票模式,投自己(因为自己的id>1 收到的另一台机器的票的id)
第1台机器收到2的票,发现集群中有一个比自己id大的机器上线了,重新投票,投id=2
第2台收到的得票数为2票,过半数,自己当选,切换模式:Leader模式
第1台就发现有Leader存在了,自己切换模式:Follower
第3台启动,发现有Leader,自动进入Follower状态
如果每个节点是同时启动的zk 同时选举自己 ,同时广播 , 同时获取别人的广播,3机器会当选
集群在运行过程中的选举流程
在某个时间点上,id=2机器挂了(leader),别的机器发现没有leader了,全体进入投票模式
先投自己,票中会携带(自己的id,自己的数据的版本号)
大家都投数据版本最新的节点做leader,如果有多个节点数据版本一样,则从中选id最大的那个作为投票目标!
Zookeeper安装部署
上传安装包并解压
tar -zxf zookeeper-3.4.6.tar.gz -C /opt/apps/修改配置文件
mv zoo_sample.cfg zoo.cfg
vi zoo.cfg
dataDir=/usr/apps/zookeeper-3.4.6/zkData
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
server.1=linux01:2888:3888
server.2=linux02:2888:3888
server.3=linux03:2888:3888
在各个节点上,手动创建数据存储目录
[root@spark01 apps]# mkdir -p /opt/appdata/zkdata/
[root@spark02 apps]# mkdir -p /opt/appdata/zkdata/
[root@spark02 apps]# mkdir -p /opt/appdata/zkdata/
在各个节点的数据存储目录中,生成一个myid文件,内容为它的id
[root@doit001~]# echo 1 > /usr/apps/zookeeper-3.4.6/zkData/myid
[root@doit002~]# echo 2 > /usr/apps/zookeeper-3.4.6/zkData/myid
[root@doit003~]# echo 3 > /usr/apps/zookeeper-3.4.6/zkData/myid
分发安装包
[root@spark01 apps]# scp -r zookeeper-3.4.6/ spark02:/opt/apps
[root@spark01 apps]# scp -r zookeeper-3.4.6/ spark03:/opt/apps
启动集群
zookeeper没有自带一个批启脚本,只能手动在每一台节点上一个一个地启动
每台机器都执行
bin/zkServer.sh start zk服务启动
bin/zkServer.sh statuszk 查看服务状态
bin/zkServer.sh stop zk停止服务