zookeeper概述
- zookeeper是⼀个开源的、分布式的,为分布式系统提供协调管理服务的开源软件。
- zookeeper通过数据模型+监听机制来驱动所有的功能。
数据模型
:建立了类似于linux文件系统的存储方式。可以通过ls命令查看。
监听机制
:可以监听上面的节点的变化,包括创建,删除,值的变化,子节点的变化(创建、删除),。
为什么需要zookeeper?
- 在分布式系统中,有⼤量的微服务协同对外提供服务,这时需要⼀个稳定的安全的协调管理⼯具,负责管理和协调这些微服务。
zookeeper安装
安装JDK,并配置环境变量
下载 Apache ZooKeeper 3.6.2 Source Release
- centos:
yum install cppunit
yum install python-setuptools
yum install openssl openssl-devel
yum install cyrus-sasl-md5 cyrus-sasl-gssapi cyrus-sasl-devel
- ubuntu:
apt-get install libcppunit-dev
apt-get install python-setuptools python2.7-dev
apt-get install openssl libssl-dev
apt-get install libsasl2-modules-gssapi-mit libsasl2-modules libsasl2-dev
- 进⼊源码⽂件夹
mvn clean install -DskipTests
- 编译c驱动
mvn clean -pfull-build
mvn install -pfull-build -DskipTests
配置解析
- ./conf/zoo_sample.cfg
#⼼跳包间隔,在这⾥每2秒发送⼀次
tickTime=2000
#初始化同步时,最⼤允许10次延时,也就是2*10秒内同步成功就认为成功
initLimit=10
#更新同步时,最⼤允许5次延时,也就是2*5秒内同步成功就认为成功
syncLimit=5
#快照或持久化数据存储路径
dataDir=/tmp/zookeeper
#zk监听端⼝
clientPort=2181
zookeeper⼯作机制
- 数据存储+监听通知机制。数据存储采⽤类似unix⽂件系统形式以及KV⽅式进⾏存储。监听通知机制是指zk通过存储和管理关键数据,接受分布式系统中的节点来注册监听关键数据的变化,当关键数据发⽣变化, zk将会通知那些注册了数据变化的节点。
zookeeper四个重要路径
- /master 群首建立,用来识别群首用的,一个集群只能有一个。
- /workers 节点作为父节点, 其下每个znode子节点保存了系统中一个可用从节点信息。
- /tasks 节点作为父节点, 其下每个znode子节点保存了所有已经创建并等待从节点执行的任务的信息, 主-从模式的应用的客户端在/tasks下添加一个znode子节点, 用来表示一个新任务, 并等待任务状态的znode节点。
- ·/assign节点作为父节点, 其下每个znode子节点保存了分配到某个从节点的一个任务信息, 当主节点为某个从节点分配了一个任务, 就会在/assign下增加一个子节点。
ZooKeeper的API
- create /path [data]
创建一个名为/path的znode节点, 并包含数据data。加-e创建临时节点,加-s创建有序节点,不加参数创建持久化节点。有序节点必须和持久或者临时绑定,没有单独存在的情况。 - delete /path
删除名为/path的znode。 - exists /path
检查是否存在名为/path的节点。 - setData /path [data]
设置名为/path的znode的数据为data。 - getData /path
返回名为/path节点的数据信息。 - getChildren /path
返回所有/path节点的所有⼦节点列表。 - addWatch /path
添加观察节点,有事件发生,就会有返回数据。
注意:ZooKeeper并不允许局部写入或读取znode节点的数据。 当设置一个znode节点的数据或读取时, znode节点的内容会被整个替换或全部读取进来。
ZooKeeper 四字命令
命令 | 说明 |
---|---|
conf | 输出相关服务配置的详细信息。 |
cons | 列出所有连接到服务器的客户端的完全的连接 / 会话的详细信息。包括“接受 / 发送”的包数量、会话 id 、操作延迟、最后的操作执行等等信息。 |
dump | 列出未经处理的会话和临时节点。 |
envi | 输出关于服务环境的详细信息(区别于 conf 命令)。 |
reqs | 列出未经处理的请求 |
ruok | 测试服务是否处于正确状态。如果确实如此,那么服务返回“imok ”,否则不做任何相应。 |
stat | 输出关于性能和连接的客户端的列表。 |
wchs | 列出服务器 watch 的详细信息。 |
wchc | 通过 session 列出服务器 watch 的详细信息,它的输出是一个与watch 相关的会话的列表。 |
wchp | 通过路径列出服务器watch 的详细信息。它输出一个与 session相关的路径。 |
znode节点的不同类型
- 当新建znode时,还需要指定该节点的类型(mode),不同的类型决定了znode节点的行为方式。
- 总之, znode一共有4种类型: 持久的(persistent) 、 临时的(ephemeral) 、 持久有序的(persistent_sequential) 和临时有序的(ephemeral_sequential)。
持久节点
- 持久的znode,如/path,只能通过调用delete来进行删除。
- 持久节点是一种非常有用的znode, 可以通过持久类型的znode为应用保存一些数据,即使znode的创建者不再属于应用系统时,数据也可以保存下来而不丢失。该数据节点被创建后,就会⼀直存在zk上,直到删除操作主动清除这个节点;
- 例如,在主-从模式例子中,需要保存从节点的任务分配情况,即使分配任务的主节点已经崩溃了,节点依然还在,可以将该任务分配给节点。
临时节点
-
一个临时节点有两种情况会被删除:1. 当创建该节点的客户端崩溃或关闭了与ZooKeeper的连接时,这个节点就会被删除。2. 主动调用delete来进行删除。
-
临时节点的⽣命周期和客户端的会话绑定在⼀起,如果客户端会话失效,这个节点会被⾃动清除;临时节点不能创建⼦节点,只能作为叶⼦节点;
-
例如, 在主从模式的例子中,当主节点创建的znode为临时节点时,该节点的存在意味着现在有一个主节点, 且主节点状态处于正常运行中。如果主znode消失后,这个znode需要和主节点一起消失。
有序节点
-
一个znode还可以设置为有序(sequential)节点。 一个有序znode节点被分配唯一的单调递增的整数。 当创建有序节点时, 一个序号会被追加到路径之后。
-
例如, 如果一个客户端创建了一个有序znode节点, 其路径为/tasks/task-, 那么ZooKeeper将会分配一个序号, 如1, 并将这个数字追加到路径之后, 最后该znode节点为/tasks/task-1。
-
有序znode通过提供了创建具有唯一名称的znode的简单方式。 同时也通过这种方式可以直观地查看znode的创建顺序。
节点的stat属性
czxid 节点被创建时的事务id
mzxid 节点最后⼀次被更新时的事务id
ctime 节点被创建的时间
mtime 节点最后⼀次被更新的时间
version 节点的版本号
cversion ⼦节点的版本号
aversion 节点acl版本号
ephemeralOwner 创建该临时节点的会话的sessionID,如果是持久节点该值为0
dataLength 数据内容的⻓度
numChildren 当前节点的⼦节点个数
pzxid 该节点的⼦节点列表最后⼀次被修改时的事务id。⼦节点列表变更才会修改该值,节点内容变更不会修改该值
⻆⾊介绍
- leader:事务请求的唯⼀调度和处理者,保证集群事务处理的顺序性;集群内部各节点的调度者;
- follower:处理客户端⾮事务请求,转发事务请求给leader服务器;参与事务请求proposal(提案)投票;参与leader选举投票
- observer:只提供⾮事务服务,通常⽤于在不影响集群事务处理能⼒的前提下提升集群的⾮事务处理能⼒;
注意:follower和observer可以统一称为learner。
版本号
-
每一个znode都有一个版本号,它随着每次数据变化而自增。这在集群环境下,多个zookeeper客户端对同一个znode进行操作的时候,这个版本号会作为数据是否有效的重要标志。
-
例如, 假设客户端c1对znode/config写入了一些配置信息, 如果另一个客户端c2同时更新了这个znode, 此时c1的版本号已经过期, c1调用setData一定不会成功。
ZooKeeper架构
- ZooKeeper服务器端运行于两种模式下:独立模式(standalone)和仲裁模式(quorum)。
独立模式
- 有一个单独的服务器, ZooKeeper状态无法复制。如果出现故障,只能重启后使用,高可用行差。
仲裁模式
- 有一组ZooKeeper服务器, 我们称为ZooKeeper集合(ZooKeeper ensemble),它们之前可以进行状态的复制,并同时为客户端提供请求。如果出现故障,可以连接到集合中的其他服务器,服务器状态与之前连接的服务器状态一致,可用性极高。
- 如果出现群首故障的时候,通过过半选举的方式,重新选举出群首。在官方的建议中,选举服务器最好是奇数,因为这样稳定性更好。例如有3个选举服务器,那么选举服务器必须有2个,符合过半原则,如果是4个服务器,那么选举服务器就得是3个,可崩溃的服务器只有一个服务器,稳定性还没有总共只有3个的好。
数据存储
- 数据存储包括内存数据存储和磁盘数据存储;磁盘数据包括事务⽇志和快照数据;
更新同步流程
- 分布式中的节点发起事务请求。
- a.如果是leader,将事务请求转化为事务提案,同时为每个提案⽣成全局的zxid; b.如果是learner,先将事务请求转发给leader, leader再将事务请求转化为事务提案,同时为每个提案⽣成全局的zxid;
- leader将需要⼴播的提案依次放到FIFO队列中,然后会按照顺序发送;
- follower接收到提案后,会将其以事务⽇志的⽅式写⼊本地磁盘,写⼊成功后,向leader发送⼀个ack回应包;
- leader收到超过半数以上follower的ack响应后,即认为发送成功,可以发送commit消息;
- leader向所有follower⼴播commit消息,同时⾃身也完成事务提交; follower接收到
commit后,执⾏事务操作。
初始化同步流程
初始化同步包括两种情况,启动选举leader以及leader崩溃;
- 投票选举出leader,根据两个要素来决定谁是leader<sid,zxid>;如果zxid越⼤,谁来当
leader;如果zxid相等, sid越⼤当选;
注:sid号建议是网络环境和配置越好,那么号应该填写越大,sid即为myid。 - 进⾏数据同步;
有两种情况:
a. 事务在leader上提交了,过半的follower都响应ack了,但是在commit消息发出前挂了;
b. 事务在leader⽣成后, leader就挂了。
需要保证:
a. 新选举出来的leader不能包含未提交的提案;
b. 新选举的leader中含有最⼤的zxid,也就是含有最新更新的服务器。
zookeeper应⽤
- 统⼀命名服务
- 统⼀配置管理
- 分布式锁
- 分布式队列
- 负载均衡(负载均衡服务器多的话,不太合适,因为他是强一致的,是最好的结果,但不一定是最好的时间)