1、是什么?
zookeeper 动物园管理者。 起源于雅虎,由于雅虎内部系统过多且都是用动物命名的,zookeeper用于管理这些系统。由此而来。
专业术语:分布式协调服务,典型的分布式数据一致性解决方案。 可解决问题:数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列。 个人理解:就是一个可以安装在多个计算机上,保持数据一致性问题的项目。
2、部署与安装
下载zookeepe包。 安装方式分三种 单机模式,集群模式,伪集群模式。
2.1 单机模式
直接解压,将解压目录的 zoo_sample.cfg 复制重命名为zoo.cfg.
启动命令: bin/zkServer.sh start
查看运行状态: bin/zkServer.sh status
停止 ./zkServer.sh stop
重启 ./zkServer.sh restart
2.2 伪集群模式
一台计算机,启动多个zookeeper 服务形成集群。 复制 zookeeper 目录 三份,重命名为zoo1 ,zoo2,zoo3
修改三份服务的配置文件: zoo1
tickTime=2000
dataDir=/usr/zoo1/data 数据目录
dataLogDir=/usr/zoo2/logs 日志目录
clientPort=3181 每个server的clientPort都要不一样
initLimit=5
syncLimit=2
server.1=192.168.220.128:2888:3888 server.x 每个服务x都不一样
server.2=192.168.220.128:4888:5888
server.3=192.168.220.128:6888:7888
在 数据文件中新建 myid 并写入与server.X的X一样的值
echo '1' > data/myid
zoo2
tickTime=2000
dataDir=/usr/zoo2/data 数据目录
dataLogDir=/usr/zoo2/logs 日志目录
clientPort=4181 每个server的clientPort都要不一样
initLimit=5
syncLimit=2
server.1=192.168.220.128:2888:3888 server.x 每个服务x都不一样
server.2=192.168.220.128:4888:5888
server.3=192.168.220.128:6888:7888
在 数据文件中新建 myid 并写入与server.X的X一样的值
echo '2' > data/myid
zoo3
tickTime=2000
dataDir=/usr/zoo3/data 数据目录
dataLogDir=/usr/zoo3/logs 日志目录
clientPort=5181 每个server的clientPort都要不一样
initLimit=5
syncLimit=2
server.1=192.168.220.128:2888:3888 server.x 每个服务x都不一样
server.2=192.168.220.128:4888:5888
server.3=192.168.220.128:6888:7888
在 数据文件中新建 myid 并写入与server.X的X一样的值
echo '3' > data/myid
依次启动三个服务,没有顺序要求。
使用 下面命令可以查看服务的运行状态,会发现,有一个服务的Mode是 leader.领导者。其他的则是fpllower
bin/zkServer.sh status conf/zoo1.cfg
bin/zkServer.sh status conf/zoo2.cfg
bin/zkServer.sh status conf/zoo3.cfg
在服务1 上创建一个节点:
bin/zkCli.sh -server 192.168.220.128:2888:3888
create /zktest 123 /zktest 是节点 123 是值
get /zktest 获取值
链接服务2
bin/zkCli.sh -server 192.168.220.128:4888:5888
get /zktest
这时 服务2 也能取得值 123 。
三个服务,中有一个leader,两个follower.如果leader服务停止。则剩下的两个follower会选举出新的leader.
2.3 集群模式
与伪集群类似,只是配置文件中的ip和端口是主机ip
3 zookeeper 重要知识点
3.1 重要概念
zookeeper 本身就是一个分布式程序(只要半数以上节点存活,ZooKeeper就能正常服务)。 为了保证高可用,最好是以集群形态来部署ZooKeeper,只要集群中存在超过一半的、处于正常工作状态的服务器,那么整个集群就能够正常对外服务。 ZooKeeper 将数据保存在内存中,这也就保证了高吞吐量和低延迟(但是内存限制了能够存储的容量不太大,此限制也是保持znode中存储的数据量较小的进一步原因)。 ZooKeeper 是高性能的。 在“读”多于“写”的应用程序中尤其地高性能,因为“写”会导致所有的服务器间同步状态。(“读”多于“写”是协调服务的典型场景。) ZooKeeper有临时节点的概念。当创建临时节点的客户端会话一直保持活动,瞬时节点就一直存在。而当会话终结时,瞬时节点被删除。持久节点是指一旦这个ZNode被创建了,除非主动进行ZNode的移除操作,否则这个ZNode将一直保存在Zookeeper上。ZooKeeper底层其实只提供了两个功能:①管理(存储、读取)用户程序提交的数据;②为用户程序提交数据节点监听服务。
3.2 会话
ZooKeeper服务器与客户端会话。一个客户端连接是指客户端和服务器之间的一个TCP长连接。客户端启动的时候,首先会与服务器建立一个 TCP 连接,从第一次连接建立开始,客户端会话的生命周期也开始了。通过这个连接,客户端能够通过心跳检测与服务器保持有效的会话,也能够向Zookeeper服务器发送请求并接受响应,同时还能够通过该连接接收来自服务器的Watch事件通知。可以为会话来设置一个客户端会话的超时时间。当由于服务器压力太大、网络故障或是客户端主动断开连接等各种原因导致客户端连接断开时,只要在超时时间规定的时间内能够重新连接上集群中任意一台服务器,那么之前创建的会话仍然有效。在为客户端创建会话之前,服务端首先会为每个客户端都分配一个sessionID。由于 sessionID 是 Zookeeper 会话的一个重要标识,许多与会话相关的运行机制都是基于这个 sessionID 的,因此,无论是哪台服务器为客户端分配的 sessionID,都务必保证全局唯一。
3.3 节点
节点 znode,Zookeeper将所有数据存储在内存中,数据模型是一棵树(ZnodeTree),类似文件系统,例如/foo/path1。每个上都会保存自己的数据内容,同时还会保存一系列属性信息,zookeeper主要用于协同数据的存储,因此在实现时 ZNode 存储的数据大小不应超过1MB。znode可以分为持久节点和临时节点两类。所谓持久节点是指一旦这个ZNode被创建了,除非主动进行ZNode的移除操作,否则这个ZNode将一直保存在Zookeeper上。而临时节点就不一样了,它的生命周期和客户端会话绑定,一旦客户端会话失效,那么这个客户端创建的所有临时节点都会被移除,临时节点不能拥有子节点。
节点还拥有很多其他属性:
数据版本,zookeeper 的每个 ZNode 上都会存储数据,对应于每个ZNode,Zookeeper 都会为其维护一个叫作 Stat 的数据结构,Stat中记录了这个 ZNode 的三个数据版本,分别是version(当前ZNode的版本,对节点操作就会加1)、cversion(当前ZNode子节点的版本,子节点变化加1)和 aclversion(当前ZNode的ACL版本)。
事务id:zxid ,zookeeper的每次变化都会产生一个递增id,用于确定操作的先后顺序。zxid 对于整个zookeeper都是唯一的。
czxid,节点被创造的事务id。
mzxid,节点被修改的事务id。
3.4 Watcher
Watcher(事件监听器),是Zookeeper中的一个很重要的特性。Zookeeper允许客户端在指定节点上注册一些Watcher,并且在一些特定事件触发的时候,ZooKeeper服务端会将事件通知到客户端上去。概括为监视与通知机制。 1、客户端在某节点注册watcher。2、zookeeper 检测到该节点发生变化,通知客户端。3、客户端回调watcher。
3.5 ACL
Zookeeper采用ACL(AccessControlLists)策略来进行权限控制,类似于 UNIX 文件系统的权限控制。
五种权限:
(1)CREATE:数据节点创建权限,允许授权对象在该 Znode 下创建子节点 (2)DELETE:子节点删除权限,允许授权对象删除该数据节点的子节点 (3)READ:数据节点的读取权限,允许授权对象访问该数据节点并读取其数据内容或子节点列表等 (4)WRITE:数据节点更新权限,允许授权对象对该数据节点进行更新操作 (5)ADMIN:数据节点管理权限,允许授权对象对该数据节点进行 ACL 相关设置操作
3.6 角色
zookeeper 部署多个节点时,每个服务都有自己的角色 leader : 发起投票和决议,更新系统状态 follower:接受客户请求并返回结果,选举leader过程中参与投票 observer:可以接受客户链接,转发客户的写请求给leader。不参与投票。 client:客户端
4 原理
4.1 zab
为保证集群模式的数据一致性。zooKeeper有一个ZAB(zokeeper 原子广播)协议。该协议有两种模式。
恢复模式,主要用于选出leader。当leader 服务崩溃后,进入恢复模式。当新的leader 选举出来后就退出恢复模式。处于恢复模式的时候,客户端的所有请求会阻塞,服务不可用。
广播模式,主要用于数据同步。leader处理所有写操作,并把数据变化发送给所有的其他服务。
每个服务有三种状态:
leading : 当前服务为leader。
following: 当前服务为follower。
looking:当前服务不知道leader是谁,正在搜寻。
4.2 选举流程
ZK内部采用一种快速选举算法,主要取决于两个因素(myid,Zxid), myid是配置文件中维护的集群序列号,Zxid为ZK的事务id。
假设现在启动两台ZK集群,对应的myid分别为1和2,那么在启动的过程中,就会发生Leader的选举,选举过程如下
由于项目刚启动,是没有任何事务的。所以,myid=1的机器,投出去的票为(1,0),收到的票是(2,0),将收到的票跟自己投出去的票对比,优先原则Zxid大的为Leader,因为Zxid越大则说明数据越新。如果Zxid一样,默认选择myid大的为Leader, 则推荐(2,0)成为Leader。
myid=2的机器,投出去的票为(2,0), 收到的票是(1,0),按照上面的规则,选择(2,0)作为Leader。
由于zookeeper的过半原则,当达到(集群个数/2+1)台机器选择同一个机器作为Leader时,改机器会从Looking状态切换到Leader状态,而其他的机器则会切换到Follower的状态
- myid: 被推举leader的节点sid值
- zxid : 被推举leader的节点事务ID
首先比较zxid,选取zxid大的服务器。