zookeeper原理介绍

 zookeeper是什么

  ZooKeeper 是一个开放惊代码的分布式协调服务,由知名互联网公司雅虎创建,是Google。Chubby 的开源实现。ZooKeeper 的设计目标是将那些复杂且容易出错的分布式一致性服,务封装起来,构成一个高致可靠的原语集,并以一系列简单易用的接口提供给用户使用。
  ZooKeeper 是一个典型的分布式数据一致性的解决方案,分布式应用程序可以基于它实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。ZooKeeper 可以保证如下分布式一致性特性。

 Zookeeper的特点

1 最终一致性:为客户端展示同一视图,这是zookeeper最重要的功能。 
2 可靠性:如果消息被到一台服务器接受,那么它将被所有的服务器接受。 
3 实时性:Zookeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync()接口。 
4 等待无关(wait-free):慢的或者失效的client不干预快速的client的请求。 
5 原子性:更新只能成功或者失败,没有中间状态。 
6 顺序性:所有Server,同一消息发布顺序一致。

zookeeper的集群角色

zookeeper引入了Leader 、Follower 和Observer 三种角色。ZooKeeper 集群中的所有机器通过一个Leader 选举过程来选定一台被称为"Leader" 的机器, Leader 服务器为客户端提供读和写服务。除Leader 外,其他机器包括Follower 和Observer 0 Follower 和Observer 都能够提供读服务,唯一的区别在干, Observer 机器不参与Leade r 选举过程,也不参与写操作的"过半写成功"策略,因此Observer 可以在不影响写性能的情况下提升集群的读性能。

 ZAB协议

  ZooKeeperAtomic Broadcast (ZAB , ZooKeeper 原子消息广播协议),协议包括两种基本的模式,分别是崩愤恢复消息广播。当整个服务框架在启动过程中,或是当Leader 服务器出现网络中断、崩愤退出与重启等异常情况时, ZAB协议就会进入恢复模式并选举产生新的Leader 服务器。当选举产生了新的Leader 服务器,同时集群中已经有过半的机器与该Leader 服务器完成了状态同步之后,ZAB 协议就会退出恢复模式。其中,所谓的状态同步是指数据同步,用来保证集群中存在过半的机器能够和Leader 服务器的数据状态保持一致。当集群中已经有过半的Fo ll ower 服务器完成了和Leader 服务器的状态同步,那么整个服务框架就可以进入消息广播模式了。当一台同样遵守ZA B 协议的服务器启动后加入到集群中时,如果此时集群中已经存在一个Leader 服务器在负责进行消息广播,那么新加入的服务器就会自觉地进入数据恢复模式: 找到Leader 所在的服务器,并与其进行数据同步,然后一起参与到消息广播流程中去。

 

zookeeper选举 

  • 半数通过
    – 3台机器 挂一台 2>3/2
    – 4台机器 挂2台 2!>4/2  

  • A提案说,我要选自己,B你同意吗?C你同意吗?B说,我同意选A;C说,我同意选A。(注意,这里超过半数了,其实在现实世界选举已经成功了。

   但是计算机世界是很严格,另外要理解算法,要继续模拟下去。)
  • 接着B提案说,我要选自己,A你同意吗;A说,我已经超半数同意当选,你的提案无效;C说,A已经超半数同意当选,B提案无效。
  • 接着C提案说,我要选自己,A你同意吗;A说,我已经超半数同意当选,你的提案无效;B说,A已经超半数同意当选,C的提案无效。
  • 选举已经产生了Leader,后面的都是follower,只能服从Leader的命令。而且这里还有个小细节,就是其实谁先启动谁当头。

zookeeper会话(Session)

Session是指客户端会话,在讲解客户端会话之前,我们先来了解下客户端连接。在ZooKeeper中,一个客户端连接是指客户端和ZooKeeper服务器之间的TCP长连接。ZooKeeper对外的服务端口默认是2181,客户端启动时,首先会与服务器建立一个TCP连接,从第一次连接建立开始,客户端会话的生命周期也开始了,通过这个连接,客户端能够通过心跳检测和服务器保持有效的会话,也能够向ZooKeeper服务器发送请求接受响应,同时还能通过该连接接收来自服务器的Watch事件通知。Session的SessionTimeout值用来设置一个客户端会话的超时时间。当由于服务器压力太大、网络故障或是客户端主动断开连接等各种原因导致客户端连接断开时,只要在SessionTimeout规定的时间内能够重新连接上集群中任意一台服务器,那么之前创建的会话仍然有效

zookeeper数据节点(ZNode)

在谈到分布式的时候,一般『节点』指的是组成集群的每一台机器。而ZooKeeper中的数据节点是指数据模型中的数据单元,称为ZNode。ZooKeeper将所有数据存储在内存中,数据模型是一棵树(ZNode Tree),由斜杠(/)进行分割的路径,就是一个ZNode,如/hbase/master,其中hbase和master都是ZNode。每个ZNode上都会保存自己的数据内容,同时会保存一系列属性信息

注:
这里的ZNode可以理解成既是Unix里的文件又是Unix里的目录。因为每个ZNode不仅本身可以写数据(相当于Unix里的文件),还可以有下一级文件或目录(相当于Unix里的目录)。

zookeeper节点类型

持久节点(PERSISTENT) 
  所谓持久节点,是指在节点创建后,就一直存在,直到有删除操作来主动清除这个节点——不会因为创建该节点的客户端会话失效而消失。

持久顺序节点(PERSISTENT_SEQUENTIAL) 
   这类节点的基本特性和上面的节点类型是一致的。额外的特性是,在ZK中,每个父节点会为他的第一级子节点维护一份时序,会记录每个子节点创建的先后顺序。基于这个特性,在创建子节点的时候,可以设置这个属性,那么在创建节点过程中,ZK会自动为给定节点名加上一个数字后缀,作为新的节点名。这个数字后缀的范围是整型的最大值。 
在创建节点的时候只需要传入节点 “/test_”,这样之后,zookeeper自动会给”test_”后面补充数字。

临时节点(EPHEMERAL) 
  和持久节点不同的是,临时节点的生命周期和客户端会话绑定。也就是说,如果客户端会话失效,那么这个节点就会自动被清除掉。注意,这里提到的是会话失效,而非连接断开。另外,在临时节点下面不能创建子节点。 
这里还要注意一件事,就是当你客户端会话失效后,所产生的节点也不是一下子就消失了,也要过一段时间,大概是10秒以内,可以试一下,本机操作生成节点,在服务器端用命令来查看当前的节点数目,你会发现客户端已经stop,但是产生的节点还在。

临时顺序节点(EPHEMERAL_SEQUENTIAL) 
  此节点是属于临时节点,不过带有顺序,客户端会话结束节点就消失。下面是一个利用该特性的分布式锁的案例流程。 
(1)客户端调用create()方法创建名为“locknode/ 
guid-lock-”的节点,需要注意的是,这里节点的创建类型需要设置为EPHEMERAL_SEQUENTIAL。 
(2)客户端调用getChildren(“locknode”)方法来获取所有已经创建的子节点,注意,这里不注册任何Watcher。 
(3)客户端获取到所有子节点path之后,如果发现自己在步骤1中创建的节点序号最小,那么就认为这个客户端获得了锁。 
(4)如果在步骤3中发现自己并非所有子节点中最小的,说明自己还没有获取到锁。此时客户端需要找到比自己小的那个节点,然后对其调用exist()方法,同时注册事件监听。 
(5)之后当这个被关注的节点被移除了,客户端会收到相应的通知。这个时候客户端需要再次调用getChildren(“locknode”)方法来获取所有已经创建的子节点,确保自己确实是最小的节点了,然后进入步骤3。

zookeeper状态信息

每个ZNode除了存储数据内容之外,还存储了ZNode本身的一些状态信息。用 get 命令可以同时获得某个ZNode的内容和状态信息。如下:

[zk: localhost:2181(CONNECTED) 23] get /yarn-leader-election/appcluster-yarn/ActiveBreadCrumb

appcluster-yarnrm1
cZxid = 0x1b00133dc0    //Created ZXID,表示该ZNode被创建时的事务ID
ctime = Tue Jan 03 15:44:42 CST 2017    //Created Time,表示该ZNode被创建的时间
mZxid = 0x1d00000063    //Modified ZXID,表示该ZNode最后一次被更新时的事务ID
mtime = Fri Jan 06 08:44:25 CST 2017    //Modified Time,表示该节点最后一次被更新的时间
pZxid = 0x1b00133dc0    //表示该节点的子节点列表最后一次被修改时的事务ID。注意,只有子节点列表变更了才会变更pZxid,子节点内容变更不会影响pZxid。
cversion = 0    //子节点的版本号
dataVersion = 11    //数据节点的版本号
aclVersion = 0    //ACL版本号
ephemeralOwner = 0x0    //创建该节点的会话的seddionID。如果该节点是持久节点,那么这个属性值为0。
dataLength = 22    //数据内容的长度
numChildren = 0    //子节点的个数。


zookeeper配置文件

 

 

 

 

 

 

 

 

 
posted @ 2018-01-29 16:17  cornerxin  阅读(182)  评论(0编辑  收藏  举报