有趣的动物管理员(zookeeper)

profile:感谢浪潮所有老师的指导

一、什么是zookeeper?

按字面意思理解,就是动物管理员,可以用于管理hadoop家族(zoo)里的那一堆动物。zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。zookeeper常用于hbase、kafka等集群的搭建和管理。
zookeeper有两部分,一部分是Server(服务器),另一部分是Client(客户端)

  1. 服务器应用程序:实际上是分布式的,并具有通用接口,以便客户端可以连接到集群中的任何服务器并获得相同的结果。
  2. 客户端应用程序:是与分布式应用进行交互的工具。

二、zookeeper的基本服务

命名服务:按名称标识集群中的节点。它类似于DNS,但仅对于节点。

配置管理:加入节点的最近的和最新的系统配置信息。

集群管理:实时地在集群和节点状态中加入/离开节点。

选举算法:选举一个节点作为协调目的的leader。

分布式锁和队列同步服务:在修改数据的同时锁定数据。此机制可帮助你在连接其他分布式应用程序(如Apache HBase)时进行自动故障恢复。

高度可靠的数据注册表:即使在一个或几个节点关闭时也可以获得数据。

三、zookeeper的优点是什么?

  1. 简单的分布式协调过程
  2. 最终一致性:client不论连接到哪个Server,展示给它都是同一个视图,这是zookeeper最重要的性能。
  3. 实时性:Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。
  4. 序列化:根据特定规则对数据进行编码。确保应用程序运行一致。这种方法可以在MapReduce中用来协调队列以执行运行的线程。
  5. 可靠性:具有简单、健壮、良好的性能,如果消息m被到一台服务器接受,那么它将被所有的服务器接受。
  6. 原子性:数据转移完全成功或完全失败,但没有事务是部分的。
  7. 等待无关(wait-free):慢的或者失效的client不得干预快速的client的请求,使得每个client都能有效的等待。
  8. 分布式与数据复制:Zookeeper作为一个集群提供一致的数据服务,自然,它要在所有机器间做数据复制。

四、zookeeper的节点类型

PERSISTENT(持久化目录节点):客户端与zookeeper断开连接后,该节点依旧存在

PERSISTENT_SEQUENTIAL(持久化顺序编号目录节点):客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号

EPHEMERAL(临时目录节点):客户端与zookeeper断开连接后,该节点被删除

EPHEMERAL_SEQUENTIAL(临时顺序编号目录节点):客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号

五、ZooKeeper 角色:(zookeeper服务主要有两个角色leader和follower)

在一个动物园里,总不能让所有的员工一起管理园区吧,那不就成美国那种乱七八糟的国家制度了吗?三权分立会使内部资源大量的浪费,从而没有精力去处理外部事物,世界上最先进的制度应当是民主集中制。对于集群服务来说,道理也是通用的。我们就需要一个园长(leader)来处理动物园的一切内部事务(投票和系统更新),并让其他的员工管理各自所负责的区域(集群)。而其他员工又分为引导员(observer)和解说员(follower),引导员可以让参观者(client)更快地看到自己想看的动物,解说员会将动物的相关信息(result)解说给参观者。
在这里插入图片描述

六、zookeeper的工作原理及流程

1.工作原理

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与之同步
在这里插入图片描述

2.zookeeper的选举机制(选主流程)

基本概念:当leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的 Server都恢复到一个正确的状态。Zk的选举算法有两种:一种是基于basic paxos实现的,另外一种是基于fast paxos算法实现的。系统默认的选举算法为fast paxos

basic paxos流程

  • 选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server;
  • 选举线程首先向所有Server发起一次询问(包括自己);
  • 选举线程收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中;
  • 收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server;
  • 线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数, 设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。
  • 通过流程分析我们可以得出:要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1,且存活的Server的数目不得少于n+1。
    在这里插入图片描述

fast paxos流程

  • 某Server首先向所有Server提议自己要成为leader,当其它Server收到提议以后,解决epoch和 zxid的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息,重复这个流程,最后一定能选举出Leader。其流程图如下所示:
    在这里插入图片描述

3.zookeeper的同步流程

选完leader以后,zk就进入状态同步过程。
(1)leader等待server连接;
(2)Follower连接leader,将最大的zxid发送给leader;
(3)Leader根据follower的zxid确定同步点;
(4)完成同步后通知follower 已经成为uptodate状态;
(5)Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。
在这里插入图片描述

4.园长(leader)的工作流程

(1)恢复数据;
(2)维持与Learner的心跳,接收Learner请求并判断Learner的请求消息类型;
(3)Learner的消息类型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根据不同的消息类型,进行不同的处理。

PS:
PING消息是指Learner的心跳信息;REQUEST消息是Follower发送的提议信息,包括写请求及同步请求;ACK消息是 Follower的对提议的回复,超过半数的Follower通过,则commit该提议;REVALIDATE消息是用来延长SESSION有效时间。
在这里插入图片描述

5.解说员(follower)的工作流程

(1)向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);
(2)接收Leader消息并进行处理;
(3)接收Client的请求,如果为写请求,发送给Leader进行投票;
(4)返回Client结果。

PS:
Follower的消息循环处理如下几种来自Leader的消息
(1)PING消息: 心跳消息;
(2)PROPOSAL消息:Leader发起的提案,要求Follower投票;
(3)COMMIT消息:服务器端最新一次提案的信息;
(4)UPTODATE消息:表明同步完成;
(5)REVALIDATE消息:根据Leader的REVALIDATE结果,关闭待revalidate的session还是允许其接受消息;
(6)SYNC消息:返回SYNC结果到客户端,这个消息最初由客户端发起,用来强制得到最新的更新。

流程图(在实际实现中,Follower是通过5个线程来实现功能的。):
在实际实现中,Follower是通过5个线程来实现功能的

6.引导员(observer)的工作流程:

对于observer的流程不再叙述,observer流程和Follower的唯一不同的地方就是observer不会参加leader发起的投票。可以理解为引导员都是外包公司的,不是动物园正式员工,没有参与公司内部选举的权利。引导员(observer):我太难了/(ㄒoㄒ)/~~

七、zookeeper集群奇数个节点的原因

1.防止由脑裂造成的集群不可用
2.在容错能力相同的情况下,奇数台更节省资源。

八、zookeeper安装及配置详解

zookeeper官网下载地址:传送门

1.单机模式

(1)安装
单机安装非常简单,只要获取到 Zookeeper 的压缩包并解压到某个目录如:/opt/zookeeper-3.2.2 下,然后将zookeeper的二进制文件夹的位置写入环境变量的path里即可完成安装。
PS:
需要注意的是,在 3.2.2 这个版本 。Zookeeper 没有提供 windows 下的启动脚本,所以要想在 windows 下启动 Zookeeper 要自己手工写一个。

// Windows 下 Zookeeper 启动脚本
setlocal 
set ZOOCFGDIR=%~dp0%..\conf 
set ZOO_LOG_DIR=%~dp0%.. 
set ZOO_LOG4J_PROP=INFO,CONSOLE 
set CLASSPATH=%ZOOCFGDIR% 
 
set CLASSPATH=%~dp0..\*;%~dp0..\lib\*;%CLASSPATH% 
set CLASSPATH=%~dp0..\build\classes;%~dp0..\build\lib\*;%CLASSPATH% 
set ZOOCFG=%ZOOCFGDIR%\zoo.cfg 
set ZOOMAIN=org.apache.zookeeper.server.ZooKeeperServerMain 
java "-Dzookeeper.log.dir=%ZOO_LOG_DIR%" "-Dzookeeper.root.logger=%ZOO_LOG4J_PROP%" 
-cp "%CLASSPATH%" %ZOOMAIN% "%ZOOCFG%" %* 
endlocal

(2)配置
在你执行启动脚本之前,还有几个基本的配置项需要配置一下,Zookeeper 的配置文件在 conf 目录下,这个目录下有 zoo_sample.cfg 和 log4j.properties,你需要做的就是将 zoo_sample.cfg 改名为 zoo.cfg,因为 Zookeeper 在启动时会找这个文件作为默认配置文件。
在这里插入图片描述
PS:
tickTime:这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
dataDir:顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。
clientPort:这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。

当这些配置项配置好后,你现在就可以启动 Zookeeper 了,启动后要检查 Zookeeper 是否已经在服务,可以通过 netstat – ano 命令查看是否有你配置的 clientPort 端口号在监听服务。

2.集群模式

Zookeeper 的集群模式的安装和配置也不是很复杂,所要做的就是增加几个配置项。集群模式除了上面的三个配置项还要增加下面几个配置项在这里插入图片描述

  • initLimit:这个配置项是用来配置 Zookeeper 接受客户端(这里所说的客户端不是用户连接 Zookeeper 服务器的客户端,而是 Zookeeper 服务器集群中连接到 Leader 的 Follower 服务器)初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过 10 个心跳的时间(也就是 tickTime)长度后 Zookeeper 服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是 5*2000=10 秒
  • syncLimit:这个配置项标识 Leader 与 Follower 之间发送消息,请求和应答时间长度,最长不能超过多少个 tickTime 的时间长度,总的时间长度就是 2*2000=4 秒
  • server.A=B:C:D 其中 A 是一个数字,表示这个是第几号服务器;B 是这个服务器的 ip 地址;C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。如果是伪集群的配置方式,由于 B 都是一样,所以不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。
    除了修改 zoo.cfg 配置文件,集群模式下还要配置一个文件 myid,这个文件在 dataDir 目录下,这个文件里面就有一个数据就是 A 的值,Zookeeper 启动时会读取这个文件,拿到里面的数据与 zoo.cfg 里面的配置信息比较从而判断到底是那个 server。

九、数据模型

在这里插入图片描述
数据结构的特点

  • 每个子目录项如 NameService 都被称作为 znode,这个 znode 是被它所在的路径唯一标识,如 Server1 这个 znode 的标识为 /NameService/Server1。
  • znode 可以有子节点目录,并且每个 znode 可以存储数据,注意 EPHEMERAL 类型的目录节点不能有子节点目录。
  • znode 是有版本的,每个 znode 中存储的数据可以有多个版本,也就是一个访问路径中可以存储多份数据。
  • znode 可以是临时节点,一旦创建这个 znode 的客户端与服务器失去联系,这个 znode 也将自动删除,Zookeeper 的客户端和服务器通信采用长连接方式,每个客户端和服务器通过心跳来保持连接,这个连接状态称为 session,如果 znode 是临时节点,这个 session 失效,znode 也就删除了。
  • znode 的目录名可以自动编号,如 App1 已经存在,再创建的话,将会自动命名为 App2。
  • znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个是 Zookeeper 的核心特性,Zookeeper 的很多功能都是基于这个特性实现的,后面在典型的应用场景中会有实例介绍。

十、常用接口

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

十一、基本操作(JAVA)

在这里插入图片描述

十二、zookeeper的shell命令

(1)开启zookeeper

zkServer.sh start
PS:
如果是集群的话,每台机子都要输入该命令,为了方便,建议你自行写一个shell脚本,用于开启每台机子的zookeeper。

(2)连接到zookeeper服务

zkCli.sh -server 主机名/IP地址:2181
注意:2181是默认端口号,如果你修改过,请使用修改后的端口连接

(3)帮助

help
在这里插入图片描述

(4)查看当前Zookeeper中所包含的内容

ls /

在这里插入图片描述

(5)节点相关操作

1)创建一个新的Znode节点"aa",以及和它相关字符
create /aa "my first zk
默认不带编号,且持久
在这里插入图片描述
2)创建带编号的持久性节点"bb"
create -s /bb "bb"
在这里插入图片描述
3)创建不带编号的临时节点"cc"
create -e /cc "cc"
在这里插入图片描述
4)创建带编号的临时节点"dd"
create -s -e /dd "dd"
在这里插入图片描述
5)再次使用ls命令来查看现在Zookeeper的中所包含的内容
ls /
在这里插入图片描述

6)关闭本次连接,再重新打开一个连接
close
ls /
connect 主机名:2181
在这里插入图片描述
7)重新查看,临时节点已经随着上一次的会话关闭自动删除了
ls /
在这里插入图片描述
8)使用get命令来确认第二步中所创建的Znode是否包含我们创建的字符串
get /aa
在这里插入图片描述
9)通过set命令来对zk所关联的字符串进行设置
set /aa haha123
在这里插入图片描述
10)再次使用get命令来查看上次修改的内容
get /aa
在这里插入图片描述

11)将刚才创建的Znode删除
delete /aa
在这里插入图片描述
12)检查
ls /
在这里插入图片描述

(6)退出zookeeper的shell界面

quit
在这里插入图片描述

(7)查看一个文件的状态信息

stat /a
在这里插入图片描述
详细解释
zxid: 一个事务编号,zookeeper集群内部的所有事务,都有一个全局的唯一的顺序的编号
  它由两部分组成: 就是一个 64位的长整型 long
  高32位: 用来标识leader关系是否改变,如 0x2  
  低32位: 用来做当前这个leader领导期间的全局的递增的事务编号,如 00000009
在这里插入图片描述

(8)状态信息操作

1)修改节点a的数据,mZxid、dataVersion、dataLength 存储信息发生变化
set /a "aaa"
在这里插入图片描述

2)创建新的节点b,状态信息都会发生变化,zxid的事物ID也会增加
stat /b
create /b "b"
stat /b
图片丢失,不放图了

3)在a节点下面新增节点c,pZxid、cversion、numChildren 发生改变
create /a/c ""
在这里插入图片描述
4)ephemeralOwner 持久性的节点信息是0x0临时的几点信息是本次会话的sessionid,如图
在这里插入图片描述

(9)停止zookeeper服务,并查看状态

zkServer.sh stop
zkServer.sh status
将leader干掉,此时第二台机器成为leader,重新创建一个文件y,此时发现czxid的前3位和之前发生变化,说明换了leader
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

达娃里氏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值