Zookeeper安装部署

打印 上一主题 下一主题

主题 864|帖子 864|积分 2592

ZooKeeper 简介

ZooKeeper是一个开放源码的分布式应用程序协调服务,它包含一个简朴的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等。

ZooKeeper 计划目的


  • 终极一致性:client岂论毗连到哪个Server,展示给它都是同一个视图,这是zookeeper最重要的性能。
  • 可靠性:具有简朴、健壮、良好的性能,如果消息m被到一台服务器接受,那么它将被全部的服务器接受。
  • 实时性:Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。
但由于网络延时等缘故起因,Zookeeper不能保证两个客户端能同时得到刚更新的数据,如果必要最新数据,应该在读数据之前调用sync()接口。

  • 等待无关(wait-free):慢的或者失效的client不得干预快速的client的请求,使得每个client都能有效的等待。
  • 原子性:更新只能成功或者失败,没有中间状态。
  • 顺序性:包罗全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息b前发布,则在全部Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。
ZooKeeper数据模子

Zookeeper会维护一个具有层次关系的数据布局,它非常类似于一个标准的文件系统,如图所示:

Zookeeper这种数据布局有如下这些特点:
1)每个子目录项如NameService都被称作为znode,这个znode是被它所在的路径唯一标识,如Server1这个znode的标识为/NameService/Server1。
2)znode可以有子节点目录,而且每个znode可以存储数据,留意EPHEMERAL(临时的)范例的目录节点不能有子节点目录。
3)znode是有版本的(version),每个znode中存储的数据可以有多个版本,也就是一个访问路径中可以存储多份数据,version号自动增长。
4)znode的范例:

  • Persistent 节点,一旦被创建,便不会意外丢失,即使服务器全部重启也依然存在。每个 Persist 节点即可包含数据,也可包含子节点。
  • Ephemeral 节点,在创建它的客户端与服务器间的 Session 结束时自动被删除。服务器重启会导致 Session 结束,因此 Ephemeral 范例的 znode 此时也会自动删除。
  • Non-sequence 节点,多个客户端同时创建同一 Non-sequence 节点时,只有一个可创建成功,其它匀失败。而且创建出的节点名称与创建时指定的节点名完全一样。
  • Sequence 节点,创建出的节点名在指定的名称之后带有10位10进制数的序号。多个客户端创建同一名称的节点时,都能创建成功,只是序号不同。
5)znode可以被监控,包罗这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个是Zookeeper的核心特性,Zookeeper的很多功能都是基于这个特性实现的。
6)ZXID:每次对Zookeeper的状态的改变都会产生一个zxid(ZooKeeper Transaction Id),zxid是全局有序的,如果zxid1小于zxid2,则zxid1在zxid2之前发生。
ZooKeeper Session

Client和Zookeeper集群建立毗连,整个session状态变化如图所示:

如果Client因为Timeout和Zookeeper Server失去毗连,client处在CONNECTING状态,会自动尝试再去毗连Server,如果在session有效期内再次成功毗连到某个Server,则回到CONNECTED状态。
留意:如果因为网络状态不好,client和Server失去联系,client会停顿在当前状态,会尝试主动再次毗连Zookeeper Server。client不能宣称自己的session expired,session expired是由Zookeeper Server来决定的,client可以选择自己主动关闭session。
ZooKeeper Watch

Zookeeper watch是一种监听通知机制。Zookeeper全部的读操作getData(), getChildren()和 exists()都可以设置监督(watch),监督事件可以理解为一次性的触发器
官方定义如下:
a watch event is one-time trigger, sent to the client that set the watch, whichoccurs when the data for which the watch was set changes。
Watch的三个关键点:

  • (一次性触发)One-time trigger
当设置监督的数据发生改变时,该监督事件会被发送到客户端。
例如,如果客户端调用了getData(/znode1, true) 而且稍后 /znode1 节点上的数据发生了改变或者被删除了,客户端将会获取到 /znode1 发生变化的监督事件;
而如果 /znode1 再一次发生了变化,除非客户端再次对/znode1 设置监督,否则客户端不会收到事件通知。

  • (发送至客户端)Sent to the client
Zookeeper客户端和服务端是通过 socket 进行通信的,由于网络存在故障,以是监督事件很有可能不会成功地到达客户端,监督事件是异步发送至监督者的。
Zookeeper 本身提供了顺序保证(ordering guarantee):即客户端只有起首看到了监督事件后,才会感知到它所设置监督的znode发生了变化(a client will never see a change for which it has set a watch until it first sees the watch event)。
网络延迟或者其他因素可能导致不同的客户端在不同的时候感知某一监督事件,但是不同的客户端所看到的齐备具有一致的顺序。

  • (被设置 watch 的数据)The data for which the watch was set
这意味着znode节点本身具有不同的改变方式。你也可以想象 Zookeeper 维护了两条监督链表:数据监督和子节点监督(data watches and child watches) getData() 和exists()设置数据监督,getChildren()设置子节点监督。
或者你也可以想象 Zookeeper 设置的不同监督返回不同的数据,getData() 和 exists() 返回znode节点的相关信息,而getChildren() 返回子节点列表。
因此,setData() 会触发设置在某一节点上所设置的数据监督(假定命据设置成功),而一次成功的create() 操作则会出发当前节点上所设置的数据监督以及父节点的子节点监督。
一次成功的 delete操作将会触发当前节点的数据监督和子节点监督事件,同时也会触发该节点父节点的child watch。
Zookeeper 中的监督是轻量级的,因此轻易设置、维护和分发。当客户端与 Zookeeper 服务器失去联系时,客户端并不会收到监督事件的通知,只有当客户端重新毗连后,若在必要的情况下,以前注册的监督会重新被注册并触发,对于开发人员来说这通常是透明的。
只有一种情况会导致监督事件的丢失,即:通过exists()设置了某个znode节点的监督,但是如果某个客户端在此znode节点被创建和删除的时间间隔内与zookeeper服务器失去了联系,该客户端即使稍后重新毗连 zookeeper服务器后也得不到事件通知。
Consistency Guarantees

Zookeeper是一个高效的、可扩展的服务,read和write操作都被计划为快速的,read比write操作更快。
顺序一致性(Sequential Consistency):从一个客户端来的更新请求会被顺序实行。
原子性(Atomicity):更新要么成功要么失败,没有部门成功的情况。
唯一的系统镜像(Single System Image):无论客户端毗连到哪个Server,看到系统镜像是一致的。
可靠性(Reliability):更新一旦有效,持续有效,直到被覆盖。
时间线(Timeliness):保证在一定的时间内各个客户端看到的系统信息是一致的。
ZooKeeper的工作原理

在zookeeper的集群中,各个节点共有下面3种角色和4种状态:

  • 角色:leader,follower,observer
  • 状态:leading,following,observing,looking
Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议(ZooKeeper Atomic Broadcast protocol)。Zab协议有两种模式,它们分别是恢复模式(Recovery选主)和广播模式(Broadcast同步)。
当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。
为了保证事务的顺序一致性,zookeeper接纳了递增的事务id号(zxid)来标识事务。全部的提议(proposal)都在被提出的时间加上了zxid。
实现中zxid是一个64位的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于谁人leader的统治时期。低32位用于递增计数。
每个Server在工作过程中有4种状态:
LOOKING:当前Server不知道leader是谁,正在搜寻。
LEADING:当前Server即为选举出来的leader。
FOLLOWING:leader已经选举出来,当前Server与之同步。
OBSERVING:observer的举动在大多数情况下与follower完全一致,但是他们不到场选举和投票,而仅仅接受(observing)选举和投票的结果。
Leader Election

当leader崩溃或者leader失去大多数的follower,这时间zk进入恢复模式,恢复模式必要重新选举出一个新的leader,让全部的Server都恢复到一个正确的状态。
Zk的选举算法有两种:一种是基于basic paxos实现的,别的一种是基于fast paxos算法实现的。
系统默认的选举算法为fast paxos。先介绍basic paxos流程:
1 选举线程由当前Server发起选举的线程担当,其主要功能是对投票结果进行统计,并选出推荐的Server;
2 选举线程起首向全部Server发起一次询问(包罗自己);
3 选举线程收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,末了获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中;
4 收到全部Server回复以后,就计算出zxid最大的谁人Server,并将这个Server相关信息设置成下一次要投票的Server;
5 线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数,设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。
通过流程分析我们可以得出:要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1,且存活的Server的数目不得少于n+1.
每个Server启动后都会重复以上流程。在恢复模式下,如果是刚从崩溃状态恢复的或者刚启动的server还会从磁盘快照中恢复数据和会话信息,zk会记录事务日志并定期进行快照,方便在恢复时进行状态恢复。
fast paxos流程是在选举过程中,某Server起首向全部Server提议自己要成为leader,当其它Server收到提议以后,解决epoch和zxid的辩论,并接受对方的提议,然后向对方发送接受提议完成的消息,重复这个流程,末了一定能选举出Leader。
Leader工作流程

Leader主要有三个功能:

  • 恢复数据;
  • 维持与follower的心跳,吸收follower请求并判断follower的请求消息范例;
  • follower的消息范例主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根据不同的消息范例,进行不同的处置处罚。
分析:
PING消息是指follower的心跳信息;REQUEST消息是follower发送的提议信息,包罗写请求及同步请求;
ACK消息是follower的对提议的回复,凌驾半数的follower通过,则commit该提议;
REVALIDATE消息是用来延长SESSION有效时间。
Follower工作流程

Follower主要有四个功能:

  • 向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);
  • 吸收Leader消息并进行处置处罚;
  • 吸收Client的请求,如果为写请求,发送给Leader进行投票;
  • 返回Client结果。
Follower的消息循环处置处罚如下几种来自Leader的消息:

  • PING消息:心跳消息
  • PROPOSAL消息:Leader发起的提案,要求Follower投票
  • COMMIT消息:服务器端最新一次提案的信息
  • UPTODATE消息:表明同步完成
  • REVALIDATE消息:根据Leader的REVALIDATE结果,关闭待revalidate的session还是允许其接受消息
  • SYNC消息:返回SYNC结果到客户端,这个消息最初由客户端发起,用来逼迫得到最新的更新。
Zab: Broadcasting State Updates

Zookeeper Server吸收到一次request,如果是follower,会转发给leader,Leader实行请求并通过Transaction的形式广播这次实行。
Zookeeper集群如何决定一个Transaction是否被commit实行?通过“两段提交协议”(a two-phase commit):

  • Leader给全部的follower发送一个PROPOSAL消息。
  • 一个follower吸收到这次PROPOSAL消息,写到磁盘,发送给leader一个ACK消息,告知已经收到。
  • 当Leader收到法定人数(quorum)的follower的ACK时间,发送commit消息实行。
Zab协议保证:

  • 如果leader以T1和T2的顺序广播,那么全部的Server必须先实行T1,再实行T2。
  • 如果恣意一个Server以T1、T2的顺序commit实行,其他全部的Server也必须以T1、T2的顺序实行。
“两段提交协议”最大的问题是如果Leader发送了PROPOSAL消息后crash或暂时失去毗连,会导致整个集群处在一种不确定的状态(follower不知道该放弃这次提交还是实行提交)。
Zookeeper这时会选出新的leader,请求处置处罚也会移到新的leader上,不同的leader由不同的epoch标识。切换Leader时,必要解决下面两个问题:

  • Never forget delivered messages
Leader在COMMIT投递到任何一台follower之前crash,只有它自己commit了。新Leader必须保证这个事务也必须commit。

  • Let go of messages that are skipped
Leader产生某个proposal,但是在crash之前,没有follower看到这个proposal。该server恢复时,必须丢弃这个proposal。
Zookeeper会只管保证不会同时有2个活动的Leader,因为2个不同的Leader会导致集群处在一种不一致的状态,以是Zab协议同时保证:

  • 在新的leader广播Transaction之前,先前Leader commit的Transaction都会先实行。
  • 在恣意时候,都不会有2个Server同时有法定人数(quorum)的支持者。
这里的quorum是一半以上的Server数目,确切的说是有投票权利的Server(不包罗Observer)。
以上总结

Zookeeper的根本原理,数据模子,Session,Watch机制,一致性保证,Leader Election,Leader和Follower的工作流程和Zab协议。
以下部署

基础信息表格

主机名操作系统版本IP地点安装软件zookeeper-230CentOS 7.7192.168.15.230JDK1.8、zookeeper-3.6.2zookeeper-231CentOS 7.7192.168.15.231JDK1.8、zookeeper-3.6.2zookeeper-232CentOS 7.7192.168.15.232JDK1.8、zookeeper-3.6.2系统信息
  1. 实验虚拟机配置1c2g25G
  2. [root@zookeeper-230 ~]# uname -a
  3. Linux zookeeper-230 3.10.0-1062.18.1.el7.x86_64 #1 SMP Tue Mar 17 23:49:17 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
  4. [root@zookeeper-230 ~]# rpm -q centos-release
  5. centos-release-7-7.1908.0.el7.centos.x86_64
复制代码
应用信息
  1. 应用路径:/usr/local/zookeeper3.6
  2. 配置路径:/usr/local/zookeeper3.6/conf
  3. 默认日志路径:/usr/local/zookeeper3.6/logs
  4. 自建快照日志路径:/usr/local/zookeeper3.6/zkdata
  5. 自建事务日志路径:/usr/local/zookeeper3.6/zklogs
复制代码
安装JDK

官网下载最新jdk到当地,当地上传jdk安装包到服务器
官网链接:https://www.oracle.com/cn/java/technologies/javase/javase-jdk8-downloads.html
或者(此非官网地点,慎用!!!此仅作测试使用)
http://mirrors.linuxeye.com/jdk/jdk-8u261-linux-x64.tar.gz
  1. wget http://mirrors.linuxeye.com/jdk/jdk-8u261-linux-x64.tar.gz
  2. 解压
  3. tar -zxvf jdk-8u261-linux-x64.tar.gz -C /usr/local/
  4. 添加环境变量,编辑文件/etc/profile,加入下面配置保存退出
  5. vim /etc/profile
  6. export JAVA_HOME=/usr/local/jdk1.8.0_261
  7. export PATH=$JAVA_HOME/bin:$PATH
  8. export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
  9. 保存退出,然后加载环境变量
  10. source /etc/profile
  11. 验证安装是否成功
  12. java -version
复制代码
下载zookeeper安装包

官网地点:https://zookeeper.apache.org/releases.html
【留意】官网下包留意包的性质,此处为
下载最新安装包
  1. 下载zookeeper应用源码包
  2. wget https://downloads.apache.org/zookeeper/zookeeper-3.6.2/apache-zookeeper-3.6.2-bin.tar.gz
  3. 解压
  4. tar -zxvf  apache-zookeeper-3.6.2-bin.tar.gz && mv apache-zookeeper-3.6.2-bin /usr/local/zookeeper3.6
  5. 创建快照日志存放目录
  6. mkdir -p /usr/local/zookeeper3.6/zkdata
  7. 创建事务日志存放目录
  8. mkdir -p /usr/local/zookeeper3.6/zklogs
复制代码
【留意】:如果不配置zklogs,那么事务日志就会写在配置默认的dataDir目录中。这样久而久之会严重影响zk的性能。因为在zk吞吐量很高的时间,产生的事务日志和快照日志非常多。
添加zookeeper启动命令环境变量
  1. 编辑文件 /etc/profile ,在文件末尾添加语句
  2. vim /etc/profile
  3. export PATH=$PATH:/usr/local/zookeeper3.6/bin
  4. 保存退出,然后加载环境变量
  5. source /etc/profile
复制代码
zk的配置文件位置为zk文件夹下的conf目录下,具体可通过命令行进入conf目录后实行:cp ./zoo_sample.cfg ./zoo.cfg即可,写入以下配置
  1. [root@zookeeper-230 conf]# cd /usr/local/zookeeper3.6/conf && cp zoo_sample.cfg zoo.cfg
  2. vim zoo.cfg
  3. tickTime=2000
  4. initLimit=10
  5. syncLimit=5
  6. dataDir=/usr/local/zookeeper3.6/zkdata      #快照日志存储目录
  7. datalogDir=/usr/local/zookeeper3.6/zklogs    #事务日志存储目录
  8. clientPort=2181
  9. server.3=192.168.15.230:2888:3888
  10. server.2=192.168.15.231:2888:3888
  11. server.1=192.168.15.232:2888:3888
复制代码
tickTime: 服务器与客户端之间交互的根本时间单元(ms),被用来作为心跳时间,同时zk最小的会话超时时间是此时间的两倍 。
initLimit: 此配置表示允许follower毗连并同步到leader的初始化时间,它以tickTime的倍数来表示。当凌驾设置倍数的tickTime时间,则毗连失败。
syncLimit: Leader服务器与follower服务器之间信息同步允许的最大时间间隔,如果凌驾此间隔,默认follower服务器与leader服务器之中断开链接。
dataDir: 保存zk内存数据库快照路径 ,除非指定,对数据库的事务日志更新也存储在此文件夹。
dataLogDir: 保存zk日志路径,当此配置不存在时默认路径与dataDir一致 。
clientPort: 客户端访问zk时经过服务器端时的端标语,通俗说是用来监听客户端毗连的端口。
maxClientCnxns : 限定毗连到zk服务器客户端的数量
server.id=hostip:port:port : 表示了不同的zk服务器的自身标识,作为集群的一部门,每一台服务器应该知道其他服务器的信息。用户可以从“server.id=hostip:port:port” 中读取到相关信息。
在服务器的zkdata(dataDir参数所指定的目录)下创建一个文件名为myid的文件,这个文件的内容只有一行,指定的是自身的id值。
好比,服务器“1”应该在myid文件中写入“1”。这个id必须在集群环境中服务器标识中是唯一的,且巨细在1~255之间。
这一样配置中,zoo1代表第一台服务器的IP地点。
第一个端标语2888(port)是从follower毗连到leader机器的端口,第二个端口3888是用来进行leader选举时所用的端口
  1. [root@zookeeper-230 ~]# echo "1" > /usr/local/zookeeper3.6/zkdata/myid
  2. [root@zookeeper-231 ~]# echo "2" > /usr/local/zookeeper3.6/zkdata/myid
  3. [root@zookeeper-232 ~]# echo "3" > /usr/local/zookeeper3.6/zkdata/myid
复制代码
【留意】通过配置zoo.cfg文件,zk可以运行在三种模式下,分别是:单机模式、集群模式和伪集群模式。
启动zookeeper服务
  1. 各主机执行语句启动zk服务
  2. zkServer.sh start
  3. 查看zk服务状态
  4. zkServer.sh status
  5. 或用jps命令查看QuorumPeerMain进程是否存在, jps是jdk提供的一个查看当前Java进程的小工具
  6. jps
复制代码
zookeeper服务常用命令
  1. zkServer.sh start 启动
  2. zkServer.sh stop 停止
  3. zkServer.sh status 状态
  4. zkServer.sh restart 重启
复制代码
zookeeper客户端操作基础指令
  1. 创建节点: create [-s] [-e] path data acl
  2. [-s]是否有序 , [-e]是否临时, path 节点路径 ,data 数据内容,acl 数据权限。
  3. 查看节点目录信息: ls path [watch]
  4. path节点路径 , watch 为监听事件。
  5. 获取节点信息: get path [watch]
  6. path节点路径 , watch 为监听事件。
  7. 修改节点信息: set path [version]
  8. path节点路径,version 版本号,修改节点数据后递增,相当于我们数据库的版本号,作为乐观锁功能。
  9. 删除节点信息: delete path [version]
  10. path节点路径 ,version ,修改节点数据后递增,相当于我们数据库的版本号,作为乐观锁功能。
  11. 查看节点当前状态: stat path [watch]
  12. path节点路径 ,watch 为监听事件
  13. 注:[] 括号里选项内容可选择
  14. watch :为当前节点的一个监听事件,当节点被修改、删除、查看时都会触发对应分类的事件
复制代码
安装zookeeper常见问题

问题一描述:

在下载安装apache-zookeeper-3.6.2.tar.gz时,已经在conf文件夹下拷贝并重命名了一份zoo.cfg文件,结果在启动 bin 目录下的zkServer.sh文件时报错,错误信息如下?
  1. 找不到或无法加载主类 org.apache.zookeeper.server.quorum.QuorumPeerMain
复制代码
缘故起因分析:

也便是下载的是未编译的 tar 包。
注:zookeeper 从 3.5 版本以后,命名就发生了改变,如果是apache-zookeeper-3.6.2.tar.gz这般命名的,都是未编译的,而 apache-zookeeper-3.6.2-bin.tar.gz 这般命名的,才是已编译的包。
解决方案:

重新下载 apache-zookeeper-3.6.2-bin.tar.gz包,然后解压使用。
问题二描述:

在下载了已编译的 apache-zookeeper-3.6.2-bin.tar.gz 包并解压,且在conf文件夹下拷贝并重命名了一份 zoo.cfg文件后,在启动 bin 目录下的zkServer.sh文件时报错,错误信息如下?
  1. No snapshot found, but there are log entries. Something is broken!
复制代码
缘故起因分析:

这个错是在启动zk服务恢复数据报错的,因为已经安装有 其他3.* 版本,且两个版本的dirData地点都没有修改dataDir=/tmp/zookeeper,是同一个地点,以是数据也是 其他3.* 版本的数据,现在启动 3.6.2 恢复这个数据就报错了
解决方案:

将3.6.2版本conf文件夹下的 zoo.cfg 文件中的 dataDir 地点修改一下即可。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

耶耶耶耶耶

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表