ZooKeeper典型应用场景

ZooKeeper典型应用场景

转载自https://www.jianshu.com/p/84ad63127cd1java

 

ZooKeeper是一个高可用的分布式数据管理与协调框架。基于对ZAB算法的实现,该框架可以很好地保证分布式环境中数据的一致性。也是基于这样的特性,使得ZooKeeper成为了解决分布式一致性问题的利器。算法

数据发布与订阅(配置中心)

数据发布与订阅,即所谓的配置中心,顾名思义就是发布者将数据发布到ZooKeeper节点上,供订阅者进行数据订阅,进而达到动态获取数据的目的,实现配置信息的集中式管理动态更新数据库

在咱们日常的应用系统开发中,常常会碰到这样的需求:系统中须要使用一些通用的配置信息,例如机器列表信息数据库配置信息等。这些全局配置信息一般具有如下3个特性。设计模式

  • 数据量一般比较小。
  • 数据内容在运行时动态变化
  • 集群中各机器共享,配置一致

对于这样的全局配置信息就能够发布到ZooKeeper上,让客户端(集群的机器)去订阅该消息。安全

发布/订阅系统通常有两种设计模式,分别是推(Push)拉(Pull)模式。服务器

  • 推:服务端主动将数据更新发送给全部订阅的客户端。
  • 拉:客户端主动发起请求来获取最新数据,一般客户端都采用定时轮询拉取的方式。

ZooKeeper采用的是推拉相结合的方式。以下:架构

客户端想服务端注册本身须要关注的节点,一旦该节点的数据发生变动,那么服务端就会向相应的客户端发送Watcher事件通知,客户端接收到这个消息通知后,须要主动到服务端获取最新的数据(推拉结合)。并发

命名服务(Naming Service)

命名服务也是分布式系统中比较常见的一类场景。在分布式系统中,经过使用命名服务,客户端应用可以根据指定名字来获取资源或服务的地址,提供者等信息。被命名的实体一般能够是集群中的机器,提供的服务,远程对象等等——这些咱们均可以统称他们为名字(Name)。其中较为常见的就是一些分布式服务框架(如RPC、RMI)中的服务地址列表。经过在ZooKeepr里建立顺序节点,可以很容易建立一个全局惟一的路径,这个路径就能够做为一个名字app

ZooKeeper的命名服务即生成全局惟一的ID负载均衡

分布式协调/通知

ZooKeeper中特有Watcher注册异步通知机制,可以很好的实现分布式环境下不一样机器,甚至不一样系统之间的通知与协调,从而实现对数据变动的实时处理。使用方法一般是不一样的客户端都对ZK上同一个ZNode进行注册,监听ZNode的变化(包括ZNode自己内容及子节点的),若是ZNode发生了变化,那么全部订阅的客户端都可以接收到相应的Watcher通知,并作出相应的处理。

ZK的分布式协调/通知,是一种通用的分布式系统机器间的通讯方式

心跳检测

机器间的心跳检测机制是指在分布式环境中,不一样机器(或进程)之间须要检测到彼此是否在正常运行,例如A机器须要知道B机器是否正常运行。在传统的开发中,咱们一般是经过主机直接是否能够相互PING通来判断,更复杂一点的话,则会经过在机器之间创建长链接,经过TCP链接固有的心跳检测机制来实现上层机器的心跳检测,这些都是很是常见的心跳检测方法。

下面来看看如何使用ZK来实现分布式机器(进程)间的心跳检测。

基于ZK的临时节点的特性,可让不一样的进程都在ZK的一个指定节点下建立临时子节点,不一样的进程直接能够根据这个临时子节点来判断对应的进程是否存活。经过这种方式,检测和被检测系统直接并不须要直接相关联,而是经过ZK上的某个节点进行关联,大大减小了系统耦合

工做进度汇报

在一个常见的任务分发系统中,一般任务被分发到不一样的机器上执行后,须要实时地将本身的任务执行进度汇报给分发系统。这个时候就能够经过ZK来实现。在ZK上选择一个节点,每一个任务客户端都在这个节点下面建立临时子节点,这样即可以实现两个功能:

  • 经过判断临时节点是否存在来肯定任务机器是否存活
  • 各个任务机器会实时地将本身的任务执行进度写到这个临时节点上去,以便中心系统可以实时地获取到任务的执行进度

Master选举

Master选举能够说是ZooKeeper最典型的应用场景了。好比HDFS中Active NameNode的选举、YARN中Active ResourceManager的选举和HBase中Active HMaster的选举等。

针对Master选举的需求,一般状况下,咱们能够选择常见的关系型数据库中的主键特性来实现:但愿成为Master的机器都向数据库中插入一条相同主键ID的记录,数据库会帮咱们进行主键冲突检查,也就是说,只有一台机器能插入成功——那么,咱们就认为向数据库中成功插入数据的客户端机器成为Master

依靠关系型数据库的主键特性确实可以很好地保证在集群中选举出惟一的一个Master。可是,若是当前选举出的Master挂了,那么该如何处理?谁来告诉我Master挂了呢?显然,关系型数据库没法通知咱们这个事件。可是,ZooKeeper能够作到!

利用ZooKeepr的强一致性,可以很好地保证在分布式高并发状况下节点的建立必定可以保证全局惟一性,即ZooKeeper将会保证客户端没法建立一个已经存在的ZNode。也就是说,若是同时有多个客户端请求建立同一个临时节点,那么最终必定只有一个客户端请求可以建立成功。利用这个特性,就能很容易地在分布式环境中进行Master选举了。

成功建立该节点的客户端所在的机器就成为了Master。同时,其余没有成功建立该节点的客户端,都会在该节点上注册一个子节点变动的Watcher,用于监控当前Master机器是否存活,一旦发现当前的Master挂了,那么其余客户端将会从新进行Master选举

这样就实现了Master的动态选举

分布式锁

分布式锁是控制分布式系统之间同步访问共享资源的一种方式。

分布式锁又分为排他锁共享锁两种。

排他锁

排他锁(Exclusive Locks,简称X锁),又称为写锁独占锁

若是事务T1对数据对象O1加上了排他锁,那么在整个加锁期间,只容许事务T1对O1进行读取和更新操做,其余任何事务都不能在对这个数据对象进行任何类型的操做(不能再对该对象加锁),直到T1释放了排他锁。

能够看出,排他锁的核心是如何保证当前只有一个事务得到锁,而且锁被释放后,全部正在等待获取锁的事务都可以被通知到

如何利用ZooKeeper实现排他锁?

定义锁

ZooKeeper上的一个ZNode能够表示一个锁。例如/exclusive_lock/lock节点就能够被定义为一个锁。

得到锁

如上所说,把ZooKeeper上的一个ZNode看做是一个锁,得到锁就经过建立ZNode的方式来实现。全部客户端都去/exclusive_lock节点下建立临时子节点/exclusive_lock/lock。ZooKeeper会保证在全部客户端中,最终只有一个客户端可以建立成功,那么就能够认为该客户端得到了锁。同时,全部没有获取到锁的客户端就须要到/exclusive_lock节点上注册一个子节点变动的Watcher监听,以便实时监听到lock节点的变动状况。

释放锁

由于/exclusive_lock/lock是一个临时节点,所以在如下两种状况下,都有可能释放锁。

  • 当前得到锁的客户端机器发生宕机重启,那么该临时节点就会被删除,释放锁
  • 正常执行完业务逻辑后,客户端就会主动将本身建立的临时节点删除,释放锁

不管在什么状况下移除了lock节点,ZooKeeper都会通知全部在/exclusive_lock节点上注册了节点变动Watcher监听的客户端。这些客户端在接收到通知后,再次从新发起分布式锁获取,即重复『获取锁』过程。

共享锁

共享锁(Shared Locks,简称S锁),又称为读锁。若是事务T1对数据对象O1加上了共享锁,那么T1只能对O1进行读操做,其余事务也能同时对O1加共享锁(不能是排他锁),直到O1上的全部共享锁都释放后O1才能被加排他锁。

总结:能够多个事务同时得到一个对象的共享锁(同时读),有共享锁就不能再加排他锁(由于排他锁是写锁)

ZooKeeper在大型分布式系统中的应用

前面已经介绍了ZooKeeper的典型应用场景。本节将以常见的大数据产品Hadoop和HBase为例来介绍ZooKeeper在其中的应用,帮助你们更好地理解ZooKeeper的分布式应用场景。

ZooKeeper在Hadoop中的应用

在Hadoop中,ZooKeeper主要用于实现HA(Hive Availability),包括HDFS的NamaNode和YARN的ResourceManager的HA。同时,在YARN中,ZooKeepr还用来存储应用的运行状态。HDFS的NamaNode和YARN的ResourceManager利用ZooKeepr实现HA的原理是同样的,因此本节以YARN为例来介绍。

 
YARN架构体系

从上图能够看出,YARN主要由ResourceManager(RM)、NodeManager(NM)、ApplicationMaster(AM)和Container四部分组成。其中最核心的就是ResourceManager

ResourceManager负责集群中全部资源的统一管理和分配,同时接收来自各个节点(NodeManager)的资源汇报信息,并把这些信息按照必定的策略分配给各个应用程序(Application Manager),其内部维护了各个应用程序的ApplicationMaster信息、NodeManager信息以及资源使用信息等。

为了实现HA,必须有多个ResourceManager并存(通常就两个),而且只有一个ResourceManager处于Active状态,其余的则处于Standby状态,当Active节点没法正常工做(如机器宕机或重启)时,处于Standby的就会经过竞争选举产生新的Active节点

主备切换

下面咱们就来看看YARN是如何实现多个ResourceManager之间的主备切换的。

  1. 建立锁节点
    在ZooKeeper上会有一个/yarn-leader-election/appcluster-yarn的锁节点,全部的ResourceManager在启动的时候,都会去竞争写一个Lock子节点:/yarn-leader-election/appcluster-yarn/ActiveBreadCrumb,该节点是临时节点。ZooKeepr可以为咱们保证最终只有一个ResourceManager可以建立成功建立成功的那个ResourceManager就切换为Active状态没有成功的那些ResourceManager则切换为Standby状态
[zk: localhost:2181(CONNECTED) 16] get /yarn-leader-election/appcluster-yarn/ActiveBreadCrumb

appcluster-yarnrm2
cZxid = 0x1b00133dc0
ctime = Tue Jan 03 15:44:42 CST 2017
mZxid = 0x1f00000540
mtime = Sat Jan 07 00:50:20 CST 2017
pZxid = 0x1b00133dc0
cversion = 0
dataVersion = 28
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 22
numChildren = 0

能够看到此时集群中ResourceManager2为Active。

  1. 注册Watcher监听
    全部Standby状态的ResourceManager都会向/yarn-leader-election/appcluster-yarn/ActiveBreadCrumb节点注册一个节点变动的Watcher监听,利用临时节点的特性,可以快速感知到Active状态的ResourceManager的运行状况。

  2. 主备切换
    当Active状态的ResourceManager出现诸如宕机或重启的异常状况时,其在ZooKeeper上链接的客户端会话就会失效,所以/yarn-leader-election/appcluster-yarn/ActiveBreadCrumb节点就会被删除。此时其他各个Standby状态的ResourceManager就都会接收到来自ZooKeeper服务端的Watcher事件通知,而后会重复进行步骤1的操做

以上就是利用ZooKeeper来实现ResourceManager的主备切换的过程,实现了ResourceManager的HA。

HDFS中NameNode的HA的实现原理跟YARN中ResourceManager的HA的实现原理相同。其锁节点为/hadoop-ha/mycluster/ActiveBreadCrumb

ResourceManager状态存储

在 ResourceManager 中,RMStateStore 可以存储一些 RM 的内部状态信息,包括 Application 以及它们的 Attempts 信息、Delegation Token 及 Version Information 等。须要注意的是,RMStateStore 中的绝大多数状态信息都是不须要持久化存储的,由于很容易从上下文信息中将其重构出来,如资源的使用状况。在存储的设计方案中,提供了三种可能的实现,分别以下。

  • 基于内存实现,通常是用于平常开发测试。
  • 基于文件系统的实现,如HDFS。
  • 基于ZooKeeper实现。

因为这些状态信息的数据量都不是很大,所以Hadoop官方建议基于ZooKeeper来实现状态信息的存储。在ZooKeepr上,ResourceManager 的状态信息都被存储在/rmstore这个根节点下面。

[zk: localhost:2181(CONNECTED) 28] ls /rmstore/ZKRMStateRoot [RMAppRoot, AMRMTokenSecretManagerRoot, EpochNode, RMDTSecretManagerRoot, RMVersionNode] 

RMAppRoot 节点下存储的是与各个 Application 相关的信息,RMDTSecretManagerRoot 存储的是与安全相关的 Token 等信息。每一个 Active 状态的 ResourceManager 在初始化阶段都会从 ZooKeeper 上读取到这些状态信息,并根据这些状态信息继续进行相应的处理。

小结:

ZooKeepr在Hadoop中的应用主要有:

  1. HDFS中NameNode的HA和YARN中ResourceManager的HA。
  2. 存储RMStateStore状态信息

ZooKeeper在HBase中的应用

HBase主要用ZooKeeper来实现HMaster选举与主备切换、系统容错、RootRegion管理、Region状态管理和分布式SplitWAL任务管理等。

HMaster选举与主备切换

HMaster选举与主备切换的原理和HDFS中NameNode及YARN中ResourceManager的HA原理相同。

系统容错

当HBase启动时,每一个RegionServer都会到ZooKeeper的/hbase/rs节点下建立一个信息节点(下文中,咱们称该节点为"rs状态节点"),例如/hbase/rs/[Hostname],同时,HMaster会对这个节点注册监听。当某个 RegionServer 挂掉的时候,ZooKeeper会由于在一段时间内没法接受其心跳(即 Session 失效),而删除掉该 RegionServer 服务器对应的 rs 状态节点。与此同时,HMaster 则会接收到 ZooKeeper 的 NodeDelete 通知,从而感知到某个节点断开,并当即开始容错工做。

HBase为何不直接让HMaster来负责RegionServer的监控呢?若是HMaster直接经过心跳机制等来管理RegionServer的状态,随着集群愈来愈大,HMaster的管理负担会愈来愈重,另外它自身也有挂掉的可能,所以数据还须要持久化。在这种状况下,ZooKeeper就成了理想的选择。

RootRegion管理

对应HBase集群来讲,数据存储的位置信息是记录在元数据region,也就是RootRegion上的。每次客户端发起新的请求,须要知道数据的位置,就会去查询RootRegion,而RootRegion自身位置则是记录在ZooKeeper上的(默认状况下,是记录在ZooKeeper的/hbase/meta-region-server节点中)。当RootRegion发生变化,好比Region的手工移动、从新负载均衡或RootRegion所在服务器发生了故障等是,就可以经过ZooKeeper来感知到这一变化并作出一系列相应的容灾措施,从而保证客户端老是可以拿到正确的RootRegion信息。

Region管理

HBase里的Region会常常发生变动,这些变动的缘由来自于系统故障、负载均衡、配置修改、Region分裂与合并等。一旦Region发生移动,它就会经历下线(offline)和从新上线(online)的过程。

下线期间数据是不能被访问的,而且Region的这个状态变化必须让全局知晓,不然可能会出现事务性的异常。对于大的HBase集群来讲,Region的数量可能会多达十万级别,甚至更多,这样规模的Region状态管理交给ZooKeeper来作也是一个很好的选择。

分布式SplitWAL任务管理

当某台RegionServer服务器挂掉时,因为总有一部分新写入的数据尚未持久化到HFile中,所以在迁移该RegionServer的服务时,一个重要的工做就是从WAL中恢复这部分还在内存中的数据,而这部分工做最关键的一步就是SplitWAL,即HMaster须要遍历该RegionServer服务器的WAL,并按Region切分红小块移动到新的地址下,并进行日志的回放(replay)

因为单个RegionServer的日志量相对庞大(可能有上千个Region,上GB的日志),而用户又每每但愿系统可以快速完成日志的恢复工做。所以一个可行的方案是将这个处理WAL的任务分给多台RegionServer服务器来共同处理,而这就又须要一个持久化组件来辅助HMaster完成任务的分配。当前的作法是,HMaster会在ZooKeeper上建立一个SplitWAL节点(默认状况下,是/hbase/SplitWAL节点),将"哪一个RegionServer处理哪一个Region"这样的信息以列表的形式存放到该节点上,而后由各个RegionServer服务器自行到该节点上去领取任务并在任务执行成功或失败后再更新该节点的信息,以通知HMaster继续进行后面的步骤。ZooKeeper在这里担负起了分布式集群中相互通知和信息持久化的角色。

做者:Jeffbond 连接:https://www.jianshu.com/p/84ad63127cd1 來源:简书
相关文章
相关标签/搜索