1、ZooKeeper概述html
ZooKeeper是一种为分布式应用所设计的高可用、高性能且一致的开源协调服务,是Google的Chubby一个开源实现,是Hadoop和Hbase的重要组件,它提供了一项基本服务:分布式锁服务。因为ZooKeeper的开源特性,后来咱们的开发者在分布式锁的基础上,摸索了出了其余的使用方法:配置维护、组服务、分布式消息队列、分布式通知/协调等。node
zookeeper是基于内存同步数据的,因此集群内的节点其内存中的数据结构是彻底相同的,所以效率很是高。数据库
ZooKeeper具有的几个特色决定了它可以用在大型的、分布式的系统当中:apache
顺序一致性bash
从同一个客户端发起的事务请求,最终将会严格按照其发起顺序被应用到zookeeper中服务器
原子性网络
全部事物请求的处理结果在整个集群中全部机器上的应用状况是一致的,即,要么整个集群中全部机器都成功应用了某一事务,要么都没有应用,必定不会出现集群中部分机器应用了改事务,另一部分没有应用的状况。session
单一视图数据结构
不管客户端链接的是哪一个zookeeper服务器,其看到的服务端数据模型都是一致的。并发
可靠性
一旦服务端成功的应用了一个事务,并完成对客户端的响应,那么该事务所引发的服务端状态变动将会一直保留下来,除非有另外一个事务又对其进行了改变。
实时性
zookeeper并非一种强一致性,只能保证顺序一致性和最终一致性,只能称为达到了伪实时性。
2、zookeeper 数据模型
ZooKeeper拥有一个层次的命名空间,这个和标准的文件系统很是类似,如图:
ZooKeeper采用树形层次结构,树中的每一个节点被称为—Znode,Znode也能够拥有子节点。
引用方式:
Zonde经过路径引用,如同Unix中的文件路径。必须是绝对路径,所以他们必须由斜杠字符来开头。除此之外,他们必须是惟一的,也就是说每个路径只有一个表示,所以这些路径不能改变。在ZooKeeper中,路径由Unicode字符串组成,而且有一些限制。字符串"/zookeeper"用以保存管理信息,好比关键配额信息。
Znode 结构
ZooKeeper命名空间中的Znode,兼具文件和目录两种特色。既像文件同样维护着数据、元信息、ACL、时间戳等数据结构,又像目录同样能够做为路径标识的一部分。每一个Znode由3部分组成 :
一、stat:此为状态信息, 描述该Znode的版本, 权限等信息
二、data:与该Znode关联的数据
三、children:该Znode下的子节点
ZooKeeper虽然能够关联一些数据,但并无被设计为常规的数据库或者大数据存储,相反的是,它用来管理调度数据,好比分布式应用中的配置文件信息、状态信息、聚集位置等等。这些数据的共同特性就是它们都是很小的数据,一般以KB为大小单位。ZooKeeper的服务器和客户端都被设计为严格检查并限制每一个Znode的数据大小至多1M,但常规使用中应该远小于此值。
3、节点类型
ZooKeeper中的节点有两种,分别为临时节点和永久节点。节点的类型在建立时即被肯定,而且不能改变。
临时节点:该节点的生命周期依赖于建立它们的会话。一旦会话(Session)结束,临时节点将被自动删除,固然能够也能够手动删除。虽然每一个临时的Znode都会绑定到一个客户端会话,但他们对全部的客户端仍是可见的。另外,ZooKeeper的临时节点不容许拥有子节点。
永久节点:该节点的生命周期不依赖于会话,而且只有在客户端显示执行删除操做的时候,他们才能被删除。
顺序节点
当建立Znode的时候,用户能够请求在ZooKeeper的路径结尾添加一个递增的计数。这个计数对于此节点的父节点来讲是惟一的,它的格式为"%10d"(10位数字,没有数值的数位用0补充,例如"0000000001")。当计数值大于232-1时,计数器将溢出。
监视器
客户端能够在节点上设置watch,咱们称之为监视器。当节点状态发生改变时(Znode的增、删、改)将会触发watch所对应的操做。当watch被触发时,ZooKeeper将会向客户端发送且仅发送一条通知,由于watch只能被触发一次,这样能够减小网络流量。
ZooKeeper有多种记录时间的形式,其中包含如下几个主要属性:
(1) Zxid
导致ZooKeeper节点状态改变的每个操做都将使节点接收到一个Zxid格式的时间戳,而且这个时间戳全局有序。也就是说,也就是说,每一个对节点的改变都将产生一个惟一的Zxid。若是Zxid1的值小于Zxid2的值,那么Zxid1所对应的事件发生在Zxid2所对应的事件以前。实际上,ZooKeeper的每一个节点维护者三个Zxid值,为别为:cZxid、mZxid、pZxid。
一、cZxid: 是节点的建立时间所对应的Zxid格式时间戳。
二、mZxid:是节点的修改时间所对应的Zxid格式时间戳。
实现中Zxid是一个64为的数字,它高32位是epoch用来标识leader关系是否改变,每次一个leader被选出来,它都会有一个 新的epoch。低32位是个递增计数。
(2) 版本号
对节点的每个操做都将导致这个节点的版本号增长。每一个节点维护着三个版本号,他们分别为:
一、version:节点数据版本号
二、cversion:子节点版本号
三、aversion:节点所拥有的ACL版本号
ZooKeeper节点属性:
4、ZooKeeper 安装配置
ZooKeeper的工做模式有三种:单机模式、集群模式、伪集群模式。
单机模式:Zookeeper只运行在一台服务器上,适合测试环境;
伪集群模式:就是在一台物理机上运行多个Zookeeper 实例;
集群模式:Zookeeper运行于一个至少有三个节点以上集群中,适合生产环境;
Zookeeper经过复制来实现高可用性,只要集群中半数以上的节点处于可用状态,它就可以保证服务继续。为何必定要超过半数呢?这跟Zookeeper的复制策略有关:zookeeper确保对znode 树的每个修改都会被复制到集群中超过半数的节点上。
服务器角色有两种:
一、leader -主节点
二、follower -从节点
在一个集群中一般只有一个leader和多个follower,当leader下线时,follower能根据选举策略,选举一个新的leader保证集群的正常工做。
下面咱们来构建一个单机模式的ZooKeeper节点:
能够去Apache的镜像站点下载zookeeper: http://www.apache.org/dyn/closer.cgi/zookeeper/
安装ZooKeeper以前首先须要安装JDK,在oracle官网能够下载到。(建议下载rpm包安装)
一、解压zookeeper
tar xf zookeeper-3.4.9.tar.gz cd zookeeper-3.4.9
二、建立配置文件
# conf/zoo.cfg tickTime=2000 dataDir=/tmp/zookeeper clientPort=2181
三、启动服务
bin/zkServer.sh start
ZooKeeper伪集群模式
ZooKeeper提供了伪集群模式,也就是能够在同一台机器上启动多个zookeeper服务,当手头机器不足时,又须要作实验,提供了很大的便利。
注: 在同一台机器上部署3个zookeeper server时,须要为每一个server建立独立的配置文件,而且保证每一个配置文件中的端口不能冲突,除了clientPort不一样以外,另外,还要在dataDir所对应的目录中建立myid文件来指定对应的zookeeper server 实例。
须要注意的几个配置项:
clientPort端口:若是在1台机器上部署多个server,那么每台机器都要不一样的 clientPort,好比 server1是2181,server2是2182,server3是2183
dataDir和dataLogDir:dataDir和dataLogDir也须要区分下,将数据文件和日志文件分开存放,同时每一个server的这两变量所对应的路径都是不一样的
server.X和myid: server.X 这个数字就是对应,data/myid中的数字。在3个server的myid文件中分别写入了0,1,2,那么每一个server中的zoo.cfg都配 server.0 server.2,server.3就好了。由于在同一台机器上,后面连着的2个端口,3个server都不要同样,不然端口冲突
启动命令
# 这时使用单机模式的启动命令是不行的,须要在指令后面跟上不一样实例的配置文件名称。以下: bin/zkServer.sh start zoo1.cfg bin/zkServer.sh start zoo2.cfg bin/zkServer.sh start zoo3.cfg
5、集群实战 — 构建一个3节点的 ZooKeeper 集群
实验环境:
服务器IP | myid |
192.168.1.21 |
11 |
192.168.1.22 | 12 |
192.168.1.23 | 13 |
注:
(1) zk服务器集群规模不得小于3个节点
(2) 要求各服务器之间系统时间要保持一致。
为了实现高可用的ZooKeeper服务,应该把zk部署在一个集群中,每台机器只跑一个zk实例。配置方式和前面差很少,只是每台机器上的配置文件 conf/zoo.cfg 彻底相同。
建立myid
# 为每台机器建立myid文件 # 192.168.1.21 echo 11 >/u01/zookeeper/zookeeper-3.4.9/data/myid # 192.168.1.22 echo 12 >/u01/zookeeper/zookeeper-3.4.9/data/myid # 192.168.1.23 echo 13 >/u01/zookeeper/zookeeper-3.4.9/data/myid
建立配置文件
能够复制 zoo_sample.cfg 到 zoo.cfg 如下为配置文件的参数设置:
# The number of milliseconds of each tick tickTime=2000 # The number of ticks that the initial # synchronization phase can take initLimit=10 # The number of ticks that can pass between # sending a request and getting an acknowledgement syncLimit=5 # the directory where the snapshot is stored. # do not use /tmp for storage, /tmp here is just # example sakes. dataDir=/u01/zookeeper/zookeeper-3.4.9/data # the port at which the clients will connect clientPort=2181 # the maximum number of client connections. # increase this if you need to handle more clients #maxClientCnxns=60 server.11=192.168.1.21:2888:3888 server.12=192.168.1.22:2888:3888 server.13=192.168.1.23:2888:3888
改好配置文件后,同步到集群内的全部节点。
经常使用配置参数解析:
dataLogdDir=/path1 # 指定事务日志的存储路径,能够和dataDir在不一样设备,这意味着可使用一个日志的专用磁盘,避免日志IO和快照竞争。 dataDir=/path2 # 运行数据的存放路径 tickTime=2000 # 这个时间是做为Zookeeper服务器之间或客户端与服务器之间维持心跳的时间间隔,每隔tickTime时间就会发送一个心跳;最小 的session过时时间为2倍tickTime maxClientCnxns=0 # 最大的并发链接数限制,设置为0或者不设置该参数,表示不进行链接数的限制。 minSessionTimeout # 最小的会话超时时间,默认值 minSession=2*tickTime maxSessionTimeout # 最大的会话超时时间,默认值 maxSession=20*tickTime initLimit=10 # 此配置表示,容许follower(相对于Leaderer言的“客户端”)链接并同步到Leader的初始化链接时间,以tickTime为单位。当初始化链接时间超过该值,则表示链接失败。 syncLimit=5 # 此配置项表示Leader与Follower之间发送消息时,请求和应答时间长度。若是follower在设置时间内不能与leader通讯,那么此follower将会被丢弃。 # 集群模式最关键的配置参数 server.11=192.168.1.21:2888:3888 # server.myid=ip:leader_port:inner_port # myid 为服务器编号,用于标识服务器,这个值必须和dataDir目录下myid文件中的值保证一致 # ip 为当前服务器IP, # leader_port Leader的端口 # inner_port zk服务器之间内部通讯端口 # 同一个集群内的服务器,须要把该集群内的服务器列表信息都写在配置文件中。
启动服务 & 查看节点的角色分配状况
# 192.168.1.21 bin/zkServer.sh start bin/zkServer.sh status # ZooKeeper JMX enabled by default # Using config: /u01/zookeeper/zookeeper-3.4.9/bin/../conf/zoo.cfg # Mode: leader # 192.168.1.22 bin/zkServer.sh start bin/zkServer.sh status # ZooKeeper JMX enabled by default # Using config: /u01/zookeeper/zookeeper-3.4.9/bin/../conf/zoo.cfg # Mode: follower # 192.168.1.23 bin/zkServer.sh start bin/zkServer.sh status # ZooKeeper JMX enabled by default # Using config: /u01/zookeeper/zookeeper-3.4.9/bin/../conf/zoo.cfg # Mode: follower
因而可知,集群已经正常运行;
6、ZooKeeper的四字命令
客户端能够经过nc或telnet链接ZooKeeper Server提交指令
简单用例:
# 检查服务器状态是否正常 echo ruok | nc localhost 2181 imok # 输出服务器配置信息 echo conf | nc localhost 2181 clientPort=2181 dataDir=/u01/zookeeper/zookeeper-3.4.9/data/version-2 dataLogDir=/u01/zookeeper/zookeeper-3.4.9/data/version-2 tickTime=2000 maxClientCnxns=60 minSessionTimeout=4000 maxSessionTimeout=40000 serverId=11 initLimit=10 syncLimit=5 electionAlg=3 electionPort=3888 quorumPort=2888 peerType=0 # 输出服务器状态信息 echo stat | nc localhost 2181 Zookeeper version: 3.4.9-1757313, built on 08/23/2016 06:50 GMT Clients: /127.0.0.1:60822[0](queued=0,recved=1,sent=0) Latency min/avg/max: 0/1/1591 Received: 200338 Sent: 200389 Connections: 1 Outstanding: 0 Zxid: 0x200498db5 Mode: follower Node count: 166
7、ZooKeeper Client 简单操做
9个基本操做指令:
简单用例:
# 链接 ZooKeeper 服务器 bin/zkCli.sh -server localhost:2181 # 查看根下有哪些节点 [zk: localhost:2181(CONNECTED) 1] ls / [controller_epoch, controller, brokers, zookeeper, admin, isr_change_notification, consumers, config] # 查看 brokers 下有哪些子节点 [zk: localhost:2181(CONNECTED) 4] ls /brokers [ids, topics, seqid] # 在根下建立一个 "tuchao" 节点,并设置数据为 "hello zookeeper" [zk: localhost:2181(CONNECTED) 5] create /tuchao "hello zookeeper" # 查看是否建立成功 [zk: localhost:2181(CONNECTED) 6] ls / [controller_epoch, controller, brokers, zookeeper, tuchao, admin, isr_change_notification, consumers, config] # 查看 /tuchao 中的数据 [zk: localhost:2181(CONNECTED) 7] get /tuchao hello zookeeper cZxid = 0x20049ab24 ctime = Sun Oct 09 15:45:02 CST 2016 mZxid = 0x20049ab24 mtime = Sun Oct 09 15:45:02 CST 2016 pZxid = 0x20049ab24 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 15 numChildren = 0 # 能够看到刚刚设置的数据。 # 修改 /tuchao 中的数据为 "Happy birthday" [zk: localhost:2181(CONNECTED) 8] set /tuchao "Happy birthday" cZxid = 0x20049ab24 ctime = Sun Oct 09 15:45:02 CST 2016 mZxid = 0x20049b2cc mtime = Sun Oct 09 15:51:17 CST 2016 pZxid = 0x20049ab24 cversion = 0 dataVersion = 1 # 能够发现,当数据变动时,数据版本号增长了。 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 14 numChildren = 0 # 再查看一次 /tuchao 中的数据 [zk: localhost:2181(CONNECTED) 9] get /tuchao Happy birthday cZxid = 0x20049ab24 ctime = Sun Oct 09 15:45:02 CST 2016 mZxid = 0x20049b2cc mtime = Sun Oct 09 15:51:17 CST 2016 pZxid = 0x20049ab24 cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 14 numChildren = 0 # 给 /tuchao 建立一个子节点 /tuchao/abc1 [zk: localhost:2181(CONNECTED) 10] create /tuchao/abc1 "abc1 node" Created /tuchao/abc1 [zk: localhost:2181(CONNECTED) 11] ls /tuchao [abc1] # 删除节点 /tuchao/abc1 [zk: localhost:2181(CONNECTED) 0] delete /tuchao/abc1 [zk: localhost:2181(CONNECTED) 1] ls /tuchao [] # 查看命令帮助,输入 h [zk: localhost:2181(CONNECTED) 2] h ZooKeeper -server host:port cmd args stat path [watch] set path data [version] ls path [watch] delquota [-n|-b] path ls2 path [watch] setAcl path acl setquota -n|-b val path history redo cmdno printwatches on|off delete path [version] sync path listquota path rmr path get path [watch] create [-s] [-e] path data acl addauth scheme auth quit getAcl path close connect host:port
参考文献:http://www.cnblogs.com/sunddenly/p/4033574.html