Zookeeper最佳实战-配置安装及集群搭建
浏览量:1550
什么是Zookeeper,Zookeeper的作用是什么,它与NameNode及HMaster如何协作?在没有接触Zookeeper的同学,或许会有这些疑问。这里给大家总结一下。
注意:节点服务器最好是奇数
1.1 什么是Zookeeper
ZooKeeper 顾名思义 动物园管理员,他是拿来管大象(Hadoop)、蜜蜂(Hive)、小猪(Pig)的管理员,Apache Hbase和 Apache Solr 以及LinkedIn sensei等项目中都采用到了Zookeeper。
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,ZooKeeper是以Fast Paxos算法为基础,实现同步服务,配置维护和命名服务等分布式应用。,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等。Zookeeper是hadoop的一个子项目,其发展历程无需赘述。在分布式应用中,由于工程师不能很好地使用锁机制,以及基于消息的协调机制不适合在某些应用中使用,因此需要有一种可靠的、可扩展的、分布式的、可配置的协调机制来统一系统的状态。Zookeeper的目的就在于此。
Zookeeper角色极其描述:

上面的解释感觉还不够,太官方了。
Zookeeper 从程序员的角度来讲可以理解为Hadoop的整体监控系统。如果namenode,HMaster宕机后,这时候Zookeeper 的重新选出leader。这是它最大的作用所在。我们先来了解下zookeeper的设计目标?
ZooKeeper很简单。ZooKeeper允许分布式进程通过与标准文件系统相似组织的共享层次结构命名空间相互协调。名称空间由数据寄存器组成 - 称为znode,在ZooKeeper中的用法 - 这些类似于文件和目录。与为存储设计的典型文件系统不同,ZooKeeper数据保存在内存中,这意味着ZooKeeper可以实现高吞吐量和低延迟数字。
ZooKeeper实现了高性能,高可用性,严格排序的访问。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服务将可用。
客户端连接到单个ZooKeeper服务器。客户端维护一个TCP连接,通过它来发送请求,获取响应,获取监视事件和发送心跳。如果到服务器的TCP连接断开,客户端将连接到不同的服务器。
zookeeper的分层命名空间示意图:

节点和临时节点
与标准文件系统不同,ZooKeeper命名空间中的每个节点都可以具有与其关联的数据以及子级。它就像有一个文件系统允许文件也是一个目录。(ZooKeeper被设计为存储协调数据:状态信息,配置,位置信息等,所以每个节点存储的数据通常很小,在字节到千字节的范围内)。
我们使用znode这个术语 来清楚地表明,正在谈论ZooKeeper数据节点。Znodes维护统计结构,包括数据更改,ACL更改和时间戳的版本号,以允许缓存验证和协调更新。每次znode的数据更改时,版本号增加。例如,每当客户端检索数据时,它也接收数据的版本。
存储在命名空间中每个znode的数据以原子方式读取和写入。读取获取与znode相关联的所有数据字节,写入替换所有数据。每个节点都有一个访问控制列表(ACL),限制谁可以做什么。
ZooKeeper也有临时节点的概念。只要创建znode的会话处于活动状态,这些znode就存在。当会话结束时,znode被删除。当您想实现[ tbd ]时,临时节点是有用的。
保证
ZooKeeper是非常快速和非常简单。因为它的目标,虽然是构建更复杂的服务的基础,如同步,它提供了一套保证。这些是:
1、顺序一致性 - 来自客户端的更新将按照它们发送的顺序应用。
2、原子性 - 更新成功或失败。没有部分结果。
3、单一系统映像 - 客户端将看到服务的相同视图,而不管它连接到的服务器。
4、可靠性 - 一旦应用更新,它将持续从那个时间直到客户端覆盖更新。
5、及时性 - 系统的客户端视图保证在一定时间范围内是最新的。
zookeeper三种运行模式:
Zookeeper 有三种运行模式:单机模式、伪集群模式和集群模式。
单机模式这种模式一般适用于开发测试环境,一方面我们没有那么多机器资源,另外就是平时的开发调试并不需要极好的稳定性。
ZooKeeper 集群通常由一组机器组成,一般 3 台以上就可以组成一个可用的 ZooKeeper 集群了。组成 ZooKeeper 集群的每台机器都会在内存中维护当前的服务器状态,并且每台机器之间都会互相保持通信。重要的一点是,只要集群中存在超过一半的机器能够正常工作,那么整个集群就能够正常对外服务。ZooKeeper 的客户端程序会选择和集群中的任意一台服务器创建一个 TCP 连接,而且一旦客户端和服务器断开连接,客户端就会自动连接到集群中的其他服务器。
伪集群模式:即集群的所有服务器都部署在一台机器上。当你手头上有一台比较好的机器,如果作为单机模式进行部署,就会浪费资源,这种情况下,ZooKeeper允许你在一台机器上通过启动不同的端口来启动多个 ZooKeeper 服务实例,以此来以集群的特性来对外服务。
1.2 Zookeeper的作用
介绍完Zookeeper以后,我们来了解一下Zookeeper到底有什么作用,这里我们主要介绍以下几点作用:
1.加强集群稳定性
2.加强集群持续性
3.保证集群有序性
4.保证集群高效
5.数据结构和等级的命名空间
那么,我们现在分别详细介绍一下zookeeper的几个作用:
加强集群稳定性
Zookeeper通过一种和文件系统很像的层级命名空间来让分布式进程互相协同工作。这些命名空间由一系列数据寄存器组成,我们也叫这些数据寄存器为znodes。这些znodes就有点像是文件系统中的文件和文件夹。和文件系统不一样的是,文件系统的文件是存储在存储区上的,而zookeeper的数据是存储在内存上的。同时,这就意味着zookeeper有着高吞吐和低延迟。
Zookeeper实现了高性能,高可靠性,和有序的访问。高性能保证了zookeeper能应用在大型的分布式系统上。高可靠性保证它不会由于单一节点的故障而造成任何问题。有序的访问能保证客户端可以实现较为复杂的同步操作。
加强集群持续性
组成Zookeeper的各个服务器必须要能相互通信。他们在内存中保存了服务器状态,也保存了操作的日志,并且持久化快照。只要大多数的服务器是可用的,那么Zookeeper就是可用的。
客户端连接到一个Zookeeper服务器,并且维持TCP连接。并且发送请求,获取回复,获取事件,并且发送连接信号。如果这个TCP连接断掉了,那么客户端可以连接另外一个服务器。
保证集群有序性
Zookeeper使用数字来对每一个更新进行标记。这样能保证Zookeeper交互的有序。后续的操作可以根据这个顺序实现诸如同步操作这样更高更抽象的服务。
保证集群高效
Zookeeper的高效更表现在以读为主的系统上。Zookeeper可以在千台服务器组成的读写比例大约为10:1的分布系统上表现优异
数据结构和等级的命名空间
Zookeeper的命名空间的结构和文件系统很像。一个名字和文件一样使用/的路径表现,zookeeper的每个节点都是被路径唯一标识
1.2 Zookeeper单实例部署安装
JDK下载地址(点击): JDK下载
![~XI~93]]KBT9{2FRJ`YGMRV.jpg](https://www.iopst.cn/zb_users/upload/2017/03/201703141489457387609623.jpg)
部署java环境
[root@Tomcat src]# tar xf jdk-8u60-linux-x64.tar.gz -C /usr/local [root@Tomcat src]# ln -s /usr/local/jdk1.8.0_60/ /usr/local/jdk [root@Tomcat src]# vim /etc/profile ####jdk java path################ export JAVA_HOME=/usr/local/jdk export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar [root@Tomcat src]# source /etc/profile
#-->检查java环境是否安装完成
[root@Tomcat src]# java -version java version "1.8.0_60" Java(TM) SE Runtime Environment (build 1.8.0_60-b27) Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
环境准备
[root@Zookeeper ~]# cat /etc/redhat-release CentOS Linux release 7.1.1503 (Core) [root@Zookeeper ~]# uname -r 3.10.0-229.el7.x86_64 [root@Zookeeper ~]# free -m total used free shared buff/cache available Mem: 3939 236 2597 16 1105 3452 Swap: 3967 0 3967 [root@Zookeeper ~]# getenforce Disabled
下载Zookeeper安装包
下载地址:
http://www-eu.apache.org/dist/zookeeper/zookeeper-3.5.0-alpha/zookeeper-3.5.0-alpha.tar.gz
GitHub源码安装,参考:
https://cwiki.apache.org/confluence/display/ZOOKEEPER/HowToContribute
下载Zookeeper安装包之后,解压到合适目录,进入zookeeper目录下的conf子目录,创建zoo.cfg或者复制模板文件并修改
[root@Zookeeper src]# tar xf zookeeper-3.5.0-alpha.tar.gz -C /data/ [root@Zookeeper src]# ln -s /data/zookeeper-3.5.0-alpha /data/zookeeper
创建数据及日志目录
[root@Zookeeper ~]# mkdir /data/zookeeper/data -p [root@Zookeeper ~]# mkdir /data/zookeeper/log -p
配置Zookeeper
[root@Zookeeper ~]# cd /data/zookeeper/conf/ [root@Zookeeper conf]# cp zoo_sample.cfg zoo.cfg [root@Zookeeper conf]# vim zoo.cfg tickTime=2000 initLimit=10 syncLimit=5 dataDir=/data/zookeeper/data/ dataLogDir=/data/zookeeper/log/ clientPort=2181
参数说明:
tickTime:这个时间是作为Zookeeper服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个tickTime时间就会发送一个心跳。(单位毫秒)
dataDir:顾名思义就是Zookeeper保存数据的目录,默认情况下,Zookeeper将写数据的日志文件也保存在这个目录里。
clientPort:这个端口就是客户端连接Zookeeper服务器的端口,Zookeeper会监听这个端口,接受客户端的访问请求。
initLimit:这个配置项是用来配置Zookeeper接受客户端(这里所说的客户端不是用户连接Zookeeper服务器的客户端,而是Zookeeper服务器集群中连接到Leader(领袖-主机)的Follower(追随者)服务器)初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过5个心跳的时间(也就是tickTime)长度后Zookeeper服务器还没有收到客户端的返回信息(领袖),那么表明这个客户端连接失败。总的时间长度就是5*2000=10秒
syncLimit:这个配置项标识Leader(领袖)与Follower(追随者)之间发送消息,请求和应答时间长度,最长不能超过多少个tickTime的时间长度,总的时间长度就是2*2000=4秒
启动zookeeper
[root@Zookeeper conf]# /data/zookeeper/bin/zkServer.sh start JMX enabled by default Using config: /data/zookeeper/bin/../conf/zoo.cfg Starting zookeeper ... STARTED
查看进程

Zookeeper服务常用命令:
启动:/data/zookeeper/bin/zkServer.sh start
关闭:/data/zookeeper/bin/zkServer.sh stop
状态: /data/zookeeper/bin/zkServer.sh status
重启:/data/zookeeper/bin/zkServer.sh restart
1.3 Zookeeper集群介绍
Zookeeper是一个为分布式应用提供一致性服务的软件,它是开源的Hadoop项目的一个子项目,并根据google发表的一篇论文来实现的。zookeeper为分布式系统提供了高笑且易于使用的协同服务,它可以为分布式应用提供相当多的服务,诸如统一命名服务,配置管理,状态同步和组服务等。zookeeper接口简单,我们不必过多地纠结在分布式系统编程难于处理的同步和一致性问题上,你可以使用zookeeper提供的现成(off-the-shelf)服务来实现来实现分布式系统额配置管理,组管理,Leader选举等功能。
Zookeeper集群部署
1.环境准备
三台机器:
192.168.56.10
192.168.56.11
192.168.56.12
2.软件版本
zookeeper-3.5.0
下载地址上面有介绍,再次不重复。
集群部署开始
1)、下载(略)
2)、安装
安装jdk,参照上面
安装Zookeeper服务:
先在三台服务server分别执行下面步骤:
解压:
[root@Zookeeper src]# tar xf zookeeper-3.5.0-alpha.tar.gz -C /data/ [root@Zookeeper src]# ln -s /data/zookeeper-3.5.0-alpha /data/zookeeper
创建数据及日志目录
[root@Zookeeper ~]# mkdir /data/zookeeper/data -p [root@Zookeeper ~]# mkdir /data/zookeeper/log -p
配置cfg文件
将conf/zoo_sample.cfg拷贝一份命名为zoo.cfg,也放在conf目录下。然后按照如下值修改其中的配置:
[root@Zookeeper ~]# cd /data/zookeeper/conf/ [root@Zookeeper conf]# cp zoo_sample.cfg zoo.cfg [root@Zookeeper conf]# vim zoo.cfg clientPort=2181 initLimit=10 autopurge.purgeInterval=24 syncLimit=10 maxClientCnxns=2000 maxSessionTimeout=60000000 tickTime=2000 dataDir=/data/zookeeper/data/ dataLogDir=/data/zookeeper/log/ autopurge.snapRetainCount=10 autopurge.purgeInterval=1 napCount=3000000 preAllocSize=131072 server.1=192.168.56.10:2888:3888 server.2=192.168.56.11:2888:3888 server.3=192.168.56.12:2888:3888
参数介绍:
1.tickTime = 2000:Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,每隔tickTime时间就会发送一个心跳。
2. initLimit: 配置 Zookeeper 接受客户端(此客户端不是用户连接 Zookeeper 服务器的客户端,而是 Zookeeper 服务器集群中连接到 Leader 的 Follower 服务器)初始化连接时最长能忍受多少个心跳时间间隔数。当已超过initLimit个tickTime长度后 Zookeeper 服务器还没有收到客户端的返回信息,则表明客户端连接失败。总的时间长度就是 initLimit * tickTime 秒。
3. syncLimit: 配置 Leader 与 Follower 之间发送消息,请求和应答时间长度,最长不能超过多少个 tickTime 的时间长度,总的时间长度就是 syncLimit * tickTime 秒
4. dataDir: Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。
5. dataLogDir:若没提供的话则用dataDir。zookeeper的持久化都存储在这两个目录里。dataLogDir里是放到的顺序日志(WAL)。而dataDir里放的是内存数据结构的snapshot,便于快速恢复。为了达到性能最大化,一般建议把dataDir和dataLogDir分到不同的磁盘上,以充分利用磁盘顺序写的特性。
6. clientPort:Zookeeper服务器监听的端口,以接受客户端的访问请求。
7. server.A=B:C:D:其中 A 是一个数字,表示这个是第几号服务器;B 是这个服务器的 ip 地址;C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,此端口就是用来执行选举时服务器相互通信的端口。如果是伪集群的配置方式,由于 B 都是一样,所以不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。
设置myid
在我们配置的data指定的目录下面,创建一个myid文件,里面内容为一个数字,用来标识当前主机,在conf/zoo.cfg中配置的server.x中x是什么数字就设置id为这个数字,如下面所示:
[root@Zookeeper1 conf]# echo "1" > /data/zookeeper/data/myid [root@Zookeeper2 conf]# echo "2" > /data/zookeeper/data/myid [root@Zookeeper3 conf]# echo "3" > /data/zookeeper/data/myid
依次启动zookeeper服务
/data/zookeeper/bin/zkServer.sh start
验证Zookeeper集群
安装完成后,可以通过zookeeper的脚本来查看zookeeper的启动状态,以及每个Zookeeper节点在集群中的角色(Leader和Follower),下面是我的Zookeeper集群各节点的查询结果:
通过上面的信息可以得知,Zookeeper3是Leader,其余两个都是Follower。
集群配置好后,可以通过其中一个Zookeeper节点连接点集群上,而且通过一个节点可以共享整个集群的服务。
测试Zookeeper是否正常工作
[root@Zookeeper1 ~]# /data/zookeeper/bin/zkCli.sh -server 192.168.56.10:2181 Connecting to 192.168.56.10:2181 ...... WATCHER:: WatchedEvent state:SyncConnected type:None path:null [zk: 192.168.56.10:2181(CONNECTED) 0]
即代表集群构建成功了,如果出现错误那应该是第三部时没有启动好集群,先利用ps aux | grep zookeeper查看是否有相应的进程的,没有话,说明集群启动出现问题,可以在每个服务器上使服务先停止,再执行启动命令。
注意:Zookeeper集群时,Zookeeper要求半数以上的机器可用,Zookeeper才能提供服务。

神回复
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。