zookeeper(入门:概念、主要元素及特性)

【百度定义相关】
先从百度看看,最基本的概括信息:
1 、 ZooKeeper是一个 分布式的(解决分布式问题) 开放源码 分布式应用程序协调服务(强调协调) ,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件( 现在已经独立出来了 )。
2、 ZooKeeper是以Fast Paxos算法为基础的。

【参考】
 网上资料很多,只是这里先看这些。
1、
zookeeper的详细介绍及使用场景: http://blog.csdn.net/king866/article/details/53992653
2、ZooKeeper的Znode剖析: https://www.cnblogs.com/Coolkaka/p/6101273.html


【zookeeper是什么?】
1 、一个分布式的服务框架
2、主要解决分布式系统中的一致性问题
3、能提供类似于文件系统目录树方式存储数据(少量的,与专门的分布式存储要区分开)
4、通过维护和监控存储数据的状态变化,达到基于数据的集群管理。

【zookeeper的元素】
并不复杂,层级关系如图(拷贝自原文):
zookeeper(入门:概念、主要元素及特性)_第1张图片

1、znode节点(对应图上/Apps及后面相关部分)---具体何用,后面再分析,先记住就行
有四种节点类型(根据客户端与zookeeper断开后的表现,以及zookeeper如何管理这些节点名字区分):
1)
PERSISTENT-持久化目录节点
      客户端与zookeeper断开连接后,该节点依旧存在
2)  PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点
    客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号
3) 
EPHEMERAL-临时目录节点
    客户端与zookeeper断开连接后,该节点被删除
4)
EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点
      客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号
这些特性是集群管理的一个基础。参见下面集群管理(GroupMembers)

2、NameService :命名服务(用它的唯一性
    
调用zk的create node api,能够很容易创建一个全局唯一的path,这个path就可以作为一个名称
   
    命名服务将名称映射为对象引用。这种“名称-引用”的关系称为名称绑定。同一个对象引用可以使用不同的名称多次被存储,但每一个名称只能准确的确定一个引用。一个命名上下文(naming context)就是一个存储名称绑定的对象。也就是说,每一个上下文对象实现一个从名称到对象引用的映射表,这个表中的名称可以表示某个应用程序的对象引用,也可以表示命名服务中的另一个上下文对象。这就意味着,如同文件系统,上下文就好像是一个有层次的表单:命名上下文相当于一个目录,用来存储指向其它目录和文件的名称,一个上下文和名称绑定的层次结构称为命名图 。(百度)

3、
configuration 配置管理 一致性、高可用性
  配置全部放到zookeeper上去,保存在 Zookeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 Zookeeper 的通知,然后从 Zookeeper 获取新的配置信息应用到系统中就好。
1 )zookeeper解决一致性、可靠性的存储问题
2)zookeeper解决通知的问题。

4、GroupMembers 集群管理
集群管理无在乎两点:是否有机器退出和加入、选举master。
1)机器退出和加入所有机器约定在父目录GroupMembers下创建临时目录节点( EPHEMERAL ,然后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与 zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除,于是,所有人都知道了。新机器加入也是类似,所有机器收到通知:新兄弟目录加入,highcount又有了。
2)选举master:所有机器创建临时顺序编号目录节( EPHEMERAL_SEQUENTIAL )点,通过master选举算法选举出来



【zookeeper中的角色】
1、Client
分布式中的一个节点,访问服务器的配置信息,周期性向server发送心跳包,server向client回应确认,如果client没有收到回应,则重定向到另一个server。这里的Server就是Zookeeper服务器,Client就是需要Zookeeper协调的应用

2、Server
zookeeper中的一个节点,为client提供所需的服务,给client回应信息表明自己是存活的。

3、Leader
连接任何一个节点,如果节点出现故障,leader自动修复,在service启动时完成leader的选举。
所有事情Leader说了算,所以易于保证一致性。

4、follower
听从leader的指令,完成选举工作

Leader最关键,负责管理整个zookeep集群,职责包括:
1)恢复数据
2)维持与follower的心跳,接收follower请求并判断follower的请求消息类型( follower的消息类型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根据不同的消息类型,进行不同的处理
zookeeper(入门:概念、主要元素及特性)_第2张图片

Client不一定都连到Leader,可以连到follower。


【leader的选举】

当leader崩溃或者leader失去大多数的follower,这时候zk进入恢复模式,恢复模式需要重新选举出一个新的leader,让所有的 Server都恢复到一个正确的状态。
Zk的选举算法有两种:一种是基于basic paxos实现的,另外一种是基于fast paxos算法实现的。

系统默认的选举算法为fast paxos
这两个的差异,其中paxos在前面文章有整理。Fast暂时不管,就是paxos的优化,加快收敛。

【watcher】
这是一个很关键的东西,就是依靠它,状态的变化才能及时传递到需要的地方,大家根据这些信息进行相应动作,从而达到协调的效果。

1、将watcher注册在需要监控信息的地方,相当于设置了一个密探:
1)要监控data_tree上的任何节点的变化(节点本身的增加,删除,数据修改,以及孩子的变化)都可以在获取该数据时注册一个Watcher。
2)
Client可以在某个ZNode上设置一个Watcher,来Watch该ZNode上的变化。如果该ZNode上有相应的变化,就会触发这个Watcher,把相应的事件通知给设置Watcher的Client
3)一次性ZooKeeper中的Watcher是一次性的,即触发一次就会被取消
ZooKeeper 都会将其从相应的存储中移除,目的是有效地减轻了服务端的压力,如果想继续Watch的话,需要客户端重新设置Watcher
4)轻量级设计:
WatchedEvent 是 ZooKeeper 整个 Watcher 通知机制的最小通知单元,这个数据结构中只包含三部分的内容:通知状态、事件类型和节点路径。也就是说,Watcher 通知非常简单,只会告诉客户端发生了事件,而不会说明事件的具体内容。例如针对 NodeDataChanged 事件,ZooKeeper 的 Watcher 只会通知客户指定数据节点的数据内容发生了变更,而对于原始数据以及变更后的新数据都无法从这个事件中直接获取到,而是需要客户端主动重新去获取数据,这也是 ZooKeeper 的 Watcher 机制的一个非常重要的特性。



【atomic broadcast原子广播(强一致性)】
Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分 别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和 leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态

【最终,zookeeper达到的效果】


1.最终一致性:client不论连接到哪个Server,展示给它都是同一个视图,这是zookeeper最重要的性能。
2 .可靠性:具有简单、健壮、良好的性能,如果消息m被到一台服务器接受,那么它将被所有的服务器接受
3 .实时性:Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。但由于网络延时等原因,Zookeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync()接口。
4 .等待无关(wait-free):慢的或者失效的client不得干预快速的client的请求,使得每个client都能有效的等待。
5.原子性:更新只能成功或者失败,没有中间状态。
.顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。

换句话说,把zookeeper作为一个可信赖的中心,各种判断可以此为依据。


【下面介绍基于zookeeper的特性,几个典型场景】
1、 数据发布与订阅
如配置管理,或者其他需要一方发布信息,大家共同得到信息的场景
发布:zookeeper提供了可靠的、一致性的存储
订阅:通过watch,在任何改变发生时,都能得到通知。
具体,比如:
1)业务逻辑中需要用到的一些全局变量,比如一些消息中间件的消息队列通常有个offset,这个offset存放在zk上,这样集群中每个发送者都能知道当前的发送进度。
2) 系统中有些信息需要动态获取,并且还会存在人工手动去修改这个信息。以前通常是暴露出接口,例如JMX接口,有了zk后,只要将这些信息存放到zk节点上即可。

2、 分布通知/协调

ZooKeeper 中特有watcher注册与异步通知机制,能够很好的实现分布式环境下不同系统之间的通知与协调,实现对数据变更的实时处理。
通常是不同系统都对 ZK上同一个znode进行注册,监听znode的变化(包括znode本身内容及子节点的),其中一个系统update了znode,那么另一个系统能 够收到通知,并作出相应处理。

1. 另一种心跳检测机制:检测系统和被检测系统之间并不直接关联起来,而是通过zk上某个节点关联,大大减少系统耦合。

2. 另一种系统调度模式(这里是推送系统):某系统有控制台和推送系统两部分组成,控制台的职责是控制推送系统进行相应的推送工作。管理人员在控制台作的一些操作,实际上是修改 了ZK上某些节点的状态,而zk就把这些变化通知给他们注册Watcher的客户端,即推送系统,于是,作出相应的推送任务。

3. 另一种工作汇报模式:一些类似于任务分发系统,子任务启动后,到zk来注册一个临时节点,并且定时将自己的进度进行汇报(将进度写回这个临时节点),这样任务管理者就能够实时知道任务进度。

总之,使用zookeeper来进行分布式通知和协调能够大大降低系统之间的耦合。



3
分布式锁

zookeeper保证数据的强一致性,即用户只要完全相信每时每刻,zk集群中任意节点(一个zk server)上的相同znode的数据是一定是相同的。锁服务可以分为两类,一个是保持独占,另一个是控制时序。

1)保持独占
,就是所有试图来获取这个锁的客户端,最终只有一个可以成功获得这把锁。通常的做法是把zk上的一个znode看作是一把锁,通过create znode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。(只有一个,共同抢,实现1个锁的持有
2)控制时序 ,就是所有视图来获取这个锁的客户端,最终都是会被安排执行,只是有个全局时序了。做法和上面基本类似,只是这里 /distribute_lock 已经预先存在,客户端在它下面创建临时有序节点(这个可以通过节点的属性控制:CreateMode.EPHEMERAL_SEQUENTIAL来指定)。Zk的父节点(/distribute_lock)维持一份sequence,保证子节点创建的时序性,从而也形成了每个客户端的全局时序。(依托 EPHEMERAL_SEQUENTIAL的顺序性


4、集群管理

1. 集群中,需要实时监控各个节点的存活性。通常通过ping等测试网络的手段,来维持心跳 。
2、基于zookeeper的特性
1)watcher:客户端在节点znode上注册一个watcher,如果znode上的状态变化,会通知客户端;创建
EPHEMERAL类型的节点,一旦客户端和服务端断开,节点会消失,知道了这个节点失效。

2)全局锁,抢选master。利用ZooKeeper的强一致性,能够保证在分布式高并发情况下节点创建的全局唯一性,即:同时有多个客户端请求创建 /currentMaster 节点,最终一定只有一个客户端请求能够创建成功。


你可能感兴趣的:(分布式系统)