柴少的官方网站 技术在学习中进步,水平在分享中升华

大数据(六)Zookeeper分布式集群的搭建

一、Zookeeper介绍

官网介绍文档:http://zookeeper.apache.org/doc/trunk/zookeeperOver.html

1.1 Zookeerper简介

        ZooKeeper本质上是一个分布式的小文件存储系统。原本是Apache Hadoop的一个组件,后来被拆分为一个Hadoop的独立子项目,现已经成为 Apache 的顶级项目。

       Zookeeper是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护、名字服务、分布式同步、组服务等。ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。分布式协调技术 主要用来解决分布式环境当中多个进程之间的同步控制,让他们有序的去访问某种临界资源,防止造成"脏数据"的后果。分布式锁是分布式协调技术实现的核心内容。

       Zookeeper 是为分布式应用程序提供高性能协调服务的工具集合,也是Google的Chubby一个开源的实现,是apache软件基金会的开源软件,是Hadoop 的分布式协调服务。它包含一个简单的原语集5,分布式应用程序可以基于它实现配置维护、命名服务、分布式同步、组服务等。Zookeeper可以用来保证数据在ZK集群之间的数据的事务性一致6。其中ZooKeeper提供通用的分布式锁服务7,用以协调分布式应用。
      Zookeeper作为Hadoop项目中的一个子项目,是 Hadoop集群管理的一个必不可少的模块,它主要用来解决分布式应用中经常遇到的数据管理问题,如集群管理、统一命名服务、分布式配置管理、分布式消息队列、分布式锁、分布式协调等。在Hadoop中,它管理Hadoop集群中的NameNode,还有在Hbase中Master Election、Server 之间状态同状步等。
   Zookeeper提供了一套很好的分布式集群管理的机制,就是它这种基于层次型的目录树的数据结构,并对树中的节点进行有效管理,从而可以设计出多种多样的分布式的数据管理模型。

     ZooKeeper性能上的特点决定了它能够用在大型的、分布式的系统当中。从可靠性方面来说,它并不会因为一个节点的错误而崩溃。除此之外,它严格的序列访问控制意味着复杂的控制原语可以应用在客户端上。ZooKeeper在一致性、可用性、容错性的保证,也是ZooKeeper的成功之处,它获得的一切成功都与它采用的协议——Zab协议是密不可分的。

1.2 Zookeeper的设计目标

  1. 简单化: ZooKeeper允许各分布式进程通过一个共享的命名空间相互联系,该命名空间类似于一个标准的层次型的文件系统:由若干注册了的数据节点构成(用Zookeeper的术语叫znode),这些节点类似于文件和目录。典型的文件系统是基于存储设备的,文传统的文件系统主要用于存储功能,然而ZooKepper的数据是保存在内存中的。也就是说,可以获得高吞吐和低延迟。ZooKeeper的实现非常重视高性能、高可靠,以及严格的有序访问。高性能保证了ZooKeeper可以用于大型的分布式系统,高可靠保证了ZooKeeper不会发生单点故障,严格的顺序访问保证了客户端可以获得复杂的同步操作原语。

  2. 健壮性: 它本身就是具有冗余结构,它构建在一系列主机之上,叫做一个”ensemble”。构成ZooKeeper服务的各服务器之间必须相互知道,它们维护着一个状态信息的内存映像,以及在持久化存储中维护着事务日志和快照。只要大部分服务器正常工作,ZooKeeper服务就能正常工作。客户端连接到一台ZooKeeper服务器。客户端维护这个TCP连接,通过这个连接,客户端可以发送请求、得到应答,得到监视事件以及发送心跳。如果这个连接断了,客户端可以连接到另一个ZooKeeper服务器。

  3. 有序性:ZooKeeper给每次更新附加一个数字标签,表明ZooKeeper中的事务顺序,后续操作可以利用这个顺序来完成更高层次的抽象功能。

  4. 速度优势:ZooKeeper特别适合于以读为主要负荷的场合。ZooKeeper可以运行在数千台机器上,如果大部分操作为读,例如读写比例为10:1,ZooKeeper的效率会很高。

ZooKeeper非常快速,非常简单。 既然它的目标是构建比较复杂的服务,比如同步,就提供了一套保证。 这些是:
顺序一致性 :来自客户端的更新将按照它们发送的顺序进行应用。
原子性 :更新成功或失败。 没有部分结果。
单系统映像 : 无论服务器连接到哪个服务器,客户端都将看到相同的服务视图。
可靠性 :一旦更新被应用,它将一直持续到客户覆盖更新。
及时性 :系统的客户观点在一定的时间范围内保证是最新的。

1.3 Zookerper的集群

图片.png

#如上图,ZK集群有五台服务器,有两种角色,除了一个领导者(Leader)以外其他的都是学习者(learner),其中领导者负责进行投票的发起和决议以及更新系统状态,学习者包括跟随者(follower)和观察者(observer),follower用于接收客户端请求并给客户端返回结果,并在选主过程中参与投票,observer可以接受客户端连接,将写请求转发给leader,但observer不参加投票过程,只同步leader的状态,observer的目的是为了扩展系统,提高读取速度。

#客户端分别连在不同的ZK服务器上,如果当数据通过客户端在某一个Server服务器上做了一次数据变更,他会把这个数据的变化同步到其他所有的服务器,同步结束之后,其他客户端都会获得这个数据的变化。

#通常Zookerper由2n+1台server组成,每个server都知道彼此的存在。每个server都维护的内存状态镜像以及持久化存储的事务日志和快照。为了保证Leader选举能过得到多数的支持,所以ZooKeeper集群的数量一般为奇数。对于2n+1台server,只要有n+1台(大多数)server可用,整个系统保持可用。

1.4 Zookerper数据模型

ZooKeeper提供的名称空间与标准文件系统非常相似。 名称是由斜杠(/)分隔的一系列路径元素。 ZooKeeper名称空间中的每个节点都由一个路径标识。

图片.png

#上图是ZooKeeper的分层命名空间。从图中我们可以看出ZooKeeper的数据模型,在结构上和标准文件系统的非常相似,都是采用这种树形层次结构,ZooKeeper树中的每个节点被称为—Znode。和文件系统的目录树一样,ZooKeeper树中的每个节点可以拥有子节点。

引用方式:

       与标准文件系统不同,ZooKeeper名称空间中的每个节点都可以有与其相关的数据以及子节点。这就像有一个文件系统,允许一个文件也是一个目录。 (ZooKeeper被设计用于存储协调数据:状态信息,配置,位置信息等,因此存储在每个节点的数据通常很小,在字节到千字节范围内)。znode通过路径引用,路径必须是绝对的,因此他们必须由斜杠字符来开头。除此以外,他们必须是唯一的,也就是说每一个路径只有一个表示,因此这些路径不能改变。在ZooKeeper中,路径由Unicode字符串组成,并且有一些限制。字符串"/zookeeper"用以保存管理信息,比如关键配额信息。

Znode结构:

         Znodes维护一个统计结构,其中包括数据更改的版本号,ACL更改和时间戳,以允许缓存验证和协调更新。每当一个znode的数据发生变化,版本号就会增加。例如,每当客户端检索数据时,它也会收到数据的版本。

        上图中每个节点称为一个znode,每个znode由3部分组成(stat:此为状态信息, 描述该znode的版本, 权限等信息。data:与该znode关联的数据。children:该znode下的子节点。)

        ZooKeeper虽然可以关联一些数据,但并没有被设计为常规的数据库或者大数据存储,相反的是,它用来管理调度数据,比如分布式应用中的配置文件信息、状态信息、汇集位置等等。这些数据的共同特性就是它们都是很小的数据,通常以KB为大小单位。ZooKeeper的服务器和客户端都被设计为严格检查并限制每个Znode的数据大小至多1M,但常规使用中应该远小于此值。

数据访问:

        存储在名称空间中每个节点上的数据是以原子方式读取和写入的。读取获得与znode关联的所有数据字节,写入将替换所有数据。每个节点都有一个访问控制列表(ACL),限制谁可以做什么。

节点类型:

        Zookeeper中的节点有两种,分为临时节点和永久节点。节点的类型在创建时即被确定,并且不能改变。

        永久节点(Nodes):该节点的声明周期不依赖于会话,并且只有在客户端显示执行删除操作的时候,他们才能删除。

        临时节点(也成短暂节点ephemeral nodes): 该节点的生命周期依赖于创建它们的会话。只要创建znode的会话处于活动状态,就会存在这些znode。当会话结束时,znode被删除当然也可以手动删除。虽然每个临时的znode都会绑定到一个客户端会话,但它们对所有的客户端还是可见的,另外临时节点不允许拥有子节点。

#ZooKeeper目录树中每一个节点对应一个Znode。每个Znode维护着一个属性结构,它包含着版本号(dataVersion),时间戳(ctime,mtime)等状态信息。ZooKeeper正是使用节点的这些特性来实现它的某些特定功能。每当Znode的数据改变时,他相应的版本号将会增加。每当客户端检索数据时,它将同时检索数据的版本号。并且如果一个客户端执行了某个节点的更新或删除操作,他也必须提供要被操作的数据版本号。如果所提供的数据版本号与实际不匹配,那么这个操作将会失败。

观察(watches):

        ZooKeeper支持watches的概念。 客户可以在znode上设置一个监视器。 当znode状态发生改变(znode的增、删、改)时将会触发watch所对应的操作。当watch被触发时,ZooKeeper将会向客户端发送且仅发送一条通知,因为watch只能被触发一次,这样可以减少网络流量。

顺序节点(唯一性的保证):

       当创建Znode的时候,用户可以请求在ZooKeeper的路径结尾添加一个递增的计数。这个计数对于此节点的父节点来说是唯一的,它的格式为“%10d”(10位数字,没有数值的数位用0补充,例如“0000000001”)。当计数值大于232-1时,计数器将溢出。
org.apache.zookeeper.CreateMode中定义了四种节点类型,分别对应:
PERSISTENT:永久节点
EPHEMERAL:临时节点
PERSISTENT_SEQUENTIAL:永久节点、序列化
EPHEMERAL_SEQUENTIAL:临时节点、序列化

1.5 简单的API

ZooKeeper的一个设计目标是提供一个非常简单的编程接口。 因此,它只支持这些操作:

1. create     :在树中的一个位置创建一个节点

2. delete   :删除一个节点

3. exists    :测试节点是否存在于某个位置

4. get data :从节点读取数据

5. set data  :将数据写入节点

6. get children :检索一个节点的子节点列表

7. sync       :等待数据传播

1.6 读写请求

图片.png

#ZooKeeper被设计为高性能的。在读取数量大于写入的应用程序中,性能特别高,因为写入操作涉及到同步所有服务器的状态。 (读出次数写入通常是协调服务的情况。)

#ZooKeeper的组件图中给出了ZooKeeper服务的高层次的组件。除了请求处理器(requestprocessor)外,构成ZooKeeper服务的每个服务器都有一个备份。复制的数据库(replicateddatabase)是一个内存数据库,包含整个数据树。为了可恢复,更新会被log到磁盘,并且在更新这个内存数据库之前,先序列化到磁盘。
#每个ZooKeeper都为客户端提供服务。客户端只连接到一个服务器,并提交请求。读请求直接由本地的复制数据库提供数据。对服务状态进行修改的请求、写请求通过一个约定的协议进行通讯。作为这个协议的一部分,所有的写请求都被传送到一个叫“首领(leader)”的服务器,而其他的服务器,叫做“(随从)followers”,follower从leader接收信息修改的提议,并同意进行。当leader发生故障时,协议的信息层(messaginglayer)关注leader的替换,并同步到所有的follower。
#ZooKeeper采用一个自定义的信息原子操作协议,由于信息层的操作是原子性的,ZooKeeper能保证本地的复制数据库不会产生不一致。当leader接收到一个写请求,它计算出写之后系统的状态,把它变成一个事务。

#与之前的3.1版本相比,3.2版本的r/w性能提高了约2倍。
博文来自:www.51niux.com

二、Zookeeper集群的搭建部署

现在我搞了3台测试机,192.168.1.38到192.168.1.40,都是Centos 7.2的操作系统,同步时间关闭selinux和firewalld这些就不说了。

Zookeeper运行需要java环境,需要安装jdk,注:每台服务器上面都需要安装zookeeper、jdk(jdk的安装部署就不写了,hadoop已经写了).

#注意:搭建zookeeper集群时,一定要先停止已经启动的zookeeper节点。

2.1 Zookeeper安装

#这是所有节点都要做的

# wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.10/zookeeper-3.4.10.tar.gz

# tar zxf zookeeper-3.4.10.tar.gz -C /home/hadoop/

# ln -s /home/hadoop/zookeeper-3.4.10 /home/hadoop/zookeeper

#cd /home/hadoop/zookeeper

# cp conf/zoo_sample.cfg conf/zoo.cfg

# vim /etc/profile  #添加环境变量

############zookeeper###############################
export ZOOKEEPER_HOME=/home/hadoop/zookeeper
export PATH=$PATH:$ZOOKEEPER_HOME/bin

# source /etc/profile

2.2 配置文件修改

# vim /home/hadoop/zookeeper/conf/zoo.cfg

tickTime=2000
initLimit=10
syncLimit=5
dataDir=/home/hadoop/zookeeperdata
clientPort=2181
dataLogDir=/home/hadoop/zookeeperdata/zoolog
server.1=192.168.1.38:2888:3888
server.2=192.168.1.39:2888:3888
server.3=192.168.1.40:2888:3888

# mkdir -p /home/hadoop/zookeeperdata
# mkdir -p /home/hadoop/zookeeperdata/zoolog

# chown -R hadoop:hadoop /home/hadoop/

#上面的参数说明:

tickTime   #作为zookeeper服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是说每个tickTime时间就会发送一个心跳,单位是毫秒。
initLimit  #zookeeper接受客户端(这里所说的客户端不是用户连接zookeeper服务器的客户端,而是zookeeper服务器集群中连接到leader的follower 服务器)初始化连接时最长能忍受多少个心跳时间间隔数。
#当已经超过10个心跳的时间(也就是tickTime)长度后 zookeeper 服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是 10*2000=20秒。
syncLimit  #标识leader与follower之间发送消息,请求和应答时间长度,最长不能超过多少个tickTime的时间长度,总的时间长度就是5*2000=10秒。
dataDir    #zookeeper保存数据的目录,默认情况下zookeeper将写数据的日志文件也保存在这个目录里
clientPort #客户端连接Zookeeper服务器的端口,Zookeeper会监听这个端口接受客户端的访问请求
dataLogDir  #如果没提供的话使用的则是dataDir。zookeeper的持久化都存储在这两个目录里。dataLogDir里是放到的顺序日志(WAL)。而dataDir里放的是内存数据结构的snapshot,便于快速恢复。为了达到性能最大化,一般建议把dataDir和dataLogDir分到不同的磁盘上,这样就可以充分利用磁盘顺序写的特性。
server.A=B:C:D  #A是一个数字,表示这个是第几号服务器,B是这个服务器的IP地址或者主机名,C第一个端口用来集群成员的信息交换,表示这个服务器与集群中的leader服务器交换信息的端口,D是在leader挂掉时专门用来进行选举leader所用的端口。

2.3 创建ServerID标识

#除了修改zoo.cfg配置文件外,zookeeper集群模式下还要配置一个myid文件,这个文件需要放在dataDir目录下。这个文件里面有一个数据就是A的值(该A就是zoo.cfg文件中server.A=B:C:D中的A),在zoo.cfg文件中配置的dataDir路径中创建myid文件。

#在192.168.1.38服务器上面创建myid文件,并设置值为1,与zoo.cfg文件里面的server.1保持一致,如下:

# echo "1">/home/hadoop/zookeeperdata/myid

#在192.168.1.39服务器上面创建myid文件,并设置值为2,与zoo.cfg文件里面的server.2保持一致,如下:

# echo "2">/home/hadoop/zookeeperdata/myid

#在192.168.1.40服务器上面创建myid文件,并设置值为3,与zoo.cfg文件里面的server.3保持一致,如下:

# echo "3">/home/hadoop/zookeeperdata/myid

2.4 启动集群并查看

#所有节点的操作

#su - hadoop -c "/home/hadoop/zookeeper/bin/zkServer.sh start"  #通过hadoop用户启动zk服务

# /home/hadoop/zookeeper/bin/zkServer.sh status   #查看zk状态

ZooKeeper JMX enabled by default
Using config: /home/hadoop/zookeeper/bin/../conf/zoo.cfg
Mode: follower

#可以看出本节点是一个追随者节点。

# /home/hadoop/zookeeper/bin/zkServer.sh status

ZooKeeper JMX enabled by default
Using config: /home/hadoop/zookeeper/bin/../conf/zoo.cfg
Mode: leader

#可以看到另一个节点是一个领导者

# jps

3718 QuorumPeerMain   #QuorumPeerMain是zookeeper 进程

# tail -f /home/hadoop/zookeeper.out   #可以看服务的启动输出

2.5 关于端口的连接

#lsof -i :2888  

#这个如果是在leader节点的话,除了自己Listen外还有其他节点跟自己连接。如果是follower节点的话,只有自己的一个随机端口跟leader节点的2888连接的信息。

# lsof -i :3888

#都是除了自己的LISTEN外,还有跟其他zookeeper节点的ESTABLISHED状态的连接。

博文来自:www.51niux.com

三、使用

3.1 使用客户端连接

# /home/hadoop/zookeeper/bin/zkCli.sh  -server localhost:2181  #命令行客户端连接zookeeper,连接成功后,会输出 ZooKeeper 的相关环境以及配置信息

[zk: localhost:2181(CONNECTED) 0] help  #可以查看帮助说明,如下图:

图片.png

# /home/hadoop/zookeeper-3.4.10/bin/zkCli.sh -server 192.168.1.40:2181  #远程客户端的连接测试

[zk: 192.168.1.40:2181(CONNECTED) 1] ls /
[zookeeper]

3.2 客户端的一些操作

创建节点:

格式:create [-s] [-e] path data acl   

#使用create命令,可以创建一个Zookeeper节点。其中,-s或-e分别指定节点特性,顺序或临时节点,若不指定,则表示持久节点;acl用来进行权限控制

] create -s /test "nihaoma"   #创建了一个/test的永久顺序节点,关联的字符串nihaoma

Created /test0000000007   #顺序节点嘛后面的一串数字是顺序递增的

] create -e /temp "buhaoa"   #创建一个临时节点/temp,关联的字符串buhaoa

Created /temp

] create /yongjiu "zouyibo"  #创建了一个永久节点/yongjiu,关联的字符串zouyibo

Created /yongjiu

] create /yongjiu/feiqi "feiyibo"

Created /yongjiu/feiqi

] quit  #退出

# /home/hadoop/zookeeper-3.4.10/bin/zkCli.sh -server 192.168.1.40:2181   #r然后重新登录

] ls /   #查询根节点,会发现创建的临时节点不存在了,而其他的节点还存在,可以看到永久节点不同于顺序节点,后面不添加数字

[zookeeper, test0000000007, yongjiu]

] ls /yongjiu  #ls命令可以列出Zookeeper指定节点下的所有子节点,只能查看指定节点下的第一级的所有子节点

[feiqi]

读取节点:

] get /   #想获取根节点数据内容和属性信息

cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x100000021
cversion = 17  
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 3   #根目录下面有几个子节点

] ls2 /  #也可以通过ls2命令查看

[ceshi, zookeeper, test0000000007, yongjiu]
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x100000023
cversion = 18
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 4

] get /yongjiu  #可以看到子节点/yongjiu的数据内容和属性

zouyibo    #可以看到起数据内容是zouyibo,我们创建节点的时候后面跟的字符串
cZxid = 0x10000001f
ctime = Sun Nov 12 00:04:15 CST 2017
mZxid = 0x10000001f
mtime = Sun Nov 12 00:04:15 CST 2017
pZxid = 0x100000020
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 7
numChildren = 1

更新节点:

格式:set path data [version]

] set /yongjiu "zouliangbo"   #更新/yongjiu节点的新内容为zouliangbo

cZxid = 0x10000001f
ctime = Sun Nov 12 00:04:15 CST 2017
mZxid = 0x100000024
mtime = Sun Nov 12 00:20:10 CST 2017    #mtime时间也变化了
pZxid = 0x100000020
cversion = 1
dataVersion = 1   #这里从0变为1说明数据已经变化了
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 10   #数据长度也变化了
numChildren = 1

删除节点:

格式:delete path [version]   # 使用delete命令可以删除Zookeeper上的指定节点,其中version也是表示数据版本

] delete /yongjiu    #若删除节点存在子节点,那么无法删除该节点,必须先删除子节点,再删除父节点。

Node not empty: /yongjiu

] delete /yongjiu/feiqi   #删除yongjiu节点下的子节点

] delete /yongjiu  #再删除节点没有提示了
] ls /   #可以看到/yongjiu节点删除掉了

[ceshi, zookeeper, test0000000007]

] rmr /ceshi   #这个rmr命令就是不管要删除的节点下面有没有子节点都删除。

3.3 ZooKeeper 常用四字命令

 ZooKeeper 支持某些特定的四字命令字母与其的交互。它们大多是查询命令,用来获取 ZooKeeper 服务的当前状态及相关信息。用户在客户端可以通过 telnet 或 nc 向 ZooKeeper 提交相应的命令

# echo stat|nc 127.0.0.1 2181  #可以看到当前连接2181端口的IP以及其他的一些信息,以及自己是什么节点

Mode: leader   #以及自己是leader节点还是follower节点

# echo dump| nc 127.0.0.1 2181  #列出未经处理的回话和临时节点

# echo ruok|nc 127.0.0.1 2181  #测试是否启动了该Server

imok   #表示已经启动

# echo conf | nc 127.0.0.1 2181  #输出相关服务配置的详细信息

# echo cons | nc 127.0.0.1 2181  #列出所有连接到服务器的客户端的完全连接/会话的详细信息。

# echo envi |nc 127.0.0.1 2181  #输出关于服务的环境的详细信息,就相当于env

# echo reqs | nc 127.0.0.1 2181  #列出未经处理的请求

# echo wchs | nc 127.0.0.1 2181 #列出watch的详细信息

# echo mntr|nc 127.0.0.1 2181  #列出一些监控信息

zk_version      3.4.10-39d3a4f269333c922ed3db283be479f9deacaa0f, built on 03/23/2017 10:13 GMT  #版本
zk_avg_latency  4     #平均延时
zk_max_latency  143   #最大延时
zk_min_latency  0      #最小延时
zk_packets_received     493   #接收到客户端请求的包数量
zk_packets_sent 492           #发送给客户单的包数量,主要是响应和通知
zk_num_alive_connections        2    #检测存活连接的节点数量
zk_outstanding_requests 0            #排队请求的数量,当ZooKeeper超过了它的处理能力时,这个值会增大,建议设置报警阀值为10
zk_server_state leader               #本zk是什么节点
zk_znode_count  5                    #znodes的数量
zk_watch_count  0                    #watches的数量
zk_ephemerals_count     0            #临时节点的数量
zk_approximate_data_size        49   #数据大小
zk_open_file_descriptor_count   34   #打开文件描述符数量
zk_max_file_descriptor_count    4096  #最大文件描述符数量
zk_followers    2                      #follower数量,leader角色才会有这个输出
zk_synced_followers     2              #同步的follower数量,leader角色才会有这个输出
zk_pending_syncs        0              #准备同步数
#zk_avg/min/max_latency :响应一个客户端请求的时间,建议这个时间大于10个Tick就报警

zabbix_api的使用请参阅链接:http://www.cnblogs.com/leesf456/p/6028416.html

作者:忙碌的柴少 分类:大数据 浏览:5126 评论:0
留言列表
发表评论
来宾的头像