文|LBD
ZooKeeper是一个开源的分布式和谐服务,由雅虎创建,是GoogleChubby的开源实现。分布式应用程序可以基于ZooKeeper实现诸如数据发布/订阅、负载均衡、定名服务、分布式和谐/关照、集群管理、Master推举、分布式锁和分布式队列等功能。
简介
ZooKeeper是一个开源的分布式和谐服务,由雅虎创建,是GoogleChubby的开源实现。分布式应用程序可以基于ZooKeeper实现诸如数据发布/订阅、负载均衡、定名服务、分布式和谐/关照、集群管理、Master推举、分布式锁和分布式队列等功能。
根本概念
本节将先容ZooKeeper的几个核心概念。这些概念贯穿于之后对ZooKeeper更深入的讲授,因此有须要预先相识这些概念。
集群脚色
在ZooKeeper中,有三种脚色:
LeaderFollowerObserver
一个ZooKeeper集群同一时候只会有一个Leader,其他都是Follower或Observer。
ZooKeeper设置很简单,每个节点的设置文件(zoo.cfg)都是一样的,只有myid文件不一样。myid的值必须是zoo.cfg中server.{数值}的{数值}部分。
zoo.cfg文件内容示例:
在装有ZooKeeper的呆板的终端实行zookeeper-serverstatus可以看当前节点的ZooKeeper是什么脚色(LeaderorFollower)。
如上,node-20-104是Leader,node-20-103是follower。
ZooKeeper默认只有Leader和Follower两种脚色,没有Observer脚色。
为了利用Observer模式,在任何想变成Observer的节点的设置文件中参加:peerType=observer并在全部server的设置文件中,设置成observer模式的server的那行设置追加:observer,比方:server.1:localhost:2888:3888:observer
ZooKeeper集群的全部呆板通过一个Leader推举过程来选定一台被称为『Leader』的呆板,Leader服务器为客户端提供读和写服务。
Follower和Observer都能提供读服务,不能提供写服务。两者唯一的区别在于,Observer呆板不参加Leader推举过程,也不参加写操纵的『过半写乐成』战略,因此Observer可以在不影响写性能的环境下提拔集群的读性能。
会话(Session)
Session是指客户端会话,在讲授客户端会话之前,我们先来相识下客户端毗连。在ZooKeeper中,一个客户端毗连是指客户端和ZooKeeper服务器之间的TCP长毗连。ZooKeeper对外的服务端口默认是2181,客户端启动时,起首会与服务器创建一个TCP毗连,从第一次毗连创建开始,客户端会话的生命周期也开始了,通过这个毗连,客户端可以或许通过心跳检测和服务器保持有效的会话,也可以或许向ZooKeeper服务器发送哀求并担当相应,同时还能通过该毗连吸取来自服务器的Watch变乱关照。
Session的SessionTimeout值用来设置一个客户端会话的超时时间。当由于服务器压力太大、网络故障或是客户端主动断开毗连等各种缘故起因导致客户端毗连断开时,只要在SessionTimeout规定的时间内可以或许重新毗连上集群中恣意一台服务器,那么之前创建的会话仍旧有效。
数据节点(ZNode)
在谈到分布式的时间,一样平常『节点』指的是构成集群的每一台呆板。而ZooKeeper中的数据节点是指数据模子中的数据单位,称为ZNode。ZooKeeper将全部数据存储在内存中,数据模子是一棵树(ZNodeTree),由斜杠(/)举行分割的路径,就是一个ZNode,如/hbase/master,此中hbase和master都是ZNode。每个ZNode上都会生存本身的数据内容,同时会生存一系列属性信息。
注:这里的ZNode可以明白成既是Unix里的文件,又是Unix里的目次。由于每个ZNode不但本身可以写数据(相称于Unix里的文件),还可以有下一级文件或目次(相称于Unix里的目次)。
在ZooKeeper中,ZNode可以分为长期节点和临时节点两类。
长期节点
所谓长期节点是指一旦这个ZNode被创建了,除非主动举行ZNode的移除操纵,否则这个ZNode将不停生存在ZooKeeper上。
临时节点
临时节点的生命周期跟客户端会话绑定,一旦客户端会话失效,那么这个客户端创建的全部临时节点都会被移除。
别的,ZooKeeper还答应用户为每个节点添加一个特别的属性:SEQUENTIAL。一旦节点被标记上这个属性,那么在这个节点被创建的时间,ZooKeeper就会主动在其节点背面追加上一个整型数字,这个整型数字是一个由父节点维护的自增数字。
版本
ZooKeeper的每个ZNode上都会存储数据,对应于每个ZNode,ZooKeeper都会为其维护一个叫作Stat的数据布局,Stat中记录了这个ZNode的三个数据版本,分别是version(当前ZNode的版本)、cversion(当前ZNode子节点的版本)和aversion(当前ZNode的ACL版本)。
状态信息
每个ZNode除了存储数据内容之外,还存储了ZNode本身的一些状态信息。用get下令可以同时得到某个ZNode的内容和状态信息。如下:
在ZooKeeper中,version属性是用来实现乐观锁机制中的『写入校验』的(包管分布式数据原子性操纵)。
事件操纵
在ZooKeeper中,能改变ZooKeeper服务器状态的操纵称为事件操纵。一样平常包罗数据节点创建与删除、数据内容更新和客户端会话创建与失效等操纵。对应每一个事件哀求,ZooKeeper都会为其分配一个全局唯一的事件ID,用ZXID表现,通常是一个64位的数字。每一个ZXID对应一次更新操纵,从这些ZXID中可以间接地辨认出ZooKeeper处理惩罚这些事件操纵哀求的全局次序。
Watcher
Watcher(变乱监听器),是ZooKeeper中一个很紧张的特性。ZooKeeper答应用户在指定节点上注册一些Watcher,而且在一些特定变乱触发的时间,ZooKeeper服务端会将变乱关照到感爱好的客户端上去。该机制是ZooKeeper实现分布式和谐服务的紧张特性。
ACL
ZooKeeper采取ACL(AccessControlLists)战略来举行权限控制。ZooKeeper界说了如下5种权限。
CREATE:创建子节点的权限。READ:获取节点数据和子节点列表的权限。WRITE:更新节点数据的权限。DELETE:删除子节点的权限。ADMIN:设置节点ACL的权限。
留意:CREATE和DELETE都是针对子节点的权限控制。
ZooKeeper典范应用场景
ZooKeeper是一个高可用的分布式数据管理与和谐框架。基于对ZAB算法的实现,该框架可以或许很好地包管分布式环境中数据的同等性。也是基于如许的特性,使得ZooKeeper成为了办理分布式同等性题目的利器。
数据发布与订阅(设置中心)
数据发布与订阅,即所谓的设置中心,顾名思义就是发布者将数据发布到ZooKeeper节点上,供订阅者举行数据订阅,进而到达动态获取数据的目标,实现设置信息的会合式管理和动态更新。
在我们平常的应用体系开辟中,常常会碰到如许的需求:体系中必要利用一些通用的设置信息,比方呆板列表信息、数据库设置信息等。这些全局设置信息通常具备以下3个特性。
数据量通常比力小。数据内容在运行时动态变革。集群中各呆板共享,设置同等。
对于如许的全局设置信息就可以发布到ZooKeeper上,让客户端(集群的呆板)去订阅该消息。
发布/订阅系同一般有两种计划模式,分别是推(Push)和拉(Pull)模式。
推:服务端主动将数据更新发送给全部订阅的客户端。
拉:客户端主动发起哀求来获取最新数据,通常客户端都采取定时轮询拉取的方式。
ZooKeeper采取的是推拉相连合的方式。如下:
客户端想服务端注册本身必要关注的节点,一旦该节点的数据发生变动,那么服务端就会向相应的客户端发送Watcher变乱关照,客户端吸取到这个消息关照后,必要主动到服务端获取最新的数据(推拉连合)。
定名服务(NamingService)
定名服务也是分布式体系中比力常见的一类场景。在分布式体系中,通过利用定名服务,客户端应用可以或许根据指定名字来获取资源或服务的地点,提供者等信息。被定名的实体通常可以是集群中的呆板,提供的服务,长途对象等等——这些我们都可以统称他们为名字(Name)。此中较为常见的就是一些分布式服务框架(如RPC、RMI)中的服务地点列表。通过在ZooKeepr里创建次序节点,可以或许很轻易创建一个全局唯一的路径,这个路径就可以作为一个名字。
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中ActiveNameNode的推举、YARN中ActiveResourceManager的推举和HBase中ActiveHMaster的推举等。
针对Master推举的需求,通常环境下,我们可以选择常见的关系型数据库中的主键特性来实现:盼望成为Master的呆板都向数据库中插入一条雷同主键ID的记录,数据库会帮我们举行主键辩论查抄,也就是说,只有一台呆板能插入乐成——那么,我们就以为向数据库中乐成插入数据的客户端呆板成为Master。
依靠关系型数据库的主键特性确实可以或许很好地包管在集群中推举出唯一的一个Master。但是,假如当前推举出的Master挂了,那么该如那边理惩罚?谁来告诉我Master挂了呢?显然,关系型数据库无法关照我们这个变乱。但是,ZooKeeper可以做到!
利用ZooKeepr的强同等性,可以或许很好地包管在分布式高并发环境下节点的创建肯定可以或许包管全局唯一性,即ZooKeeper将会包管客户端无法创建一个已经存在的ZNode。也就是说,假如同时有多个客户端哀求创建同一个临时节点,那么终极肯定只有一个客户端哀求可以或许创建乐成。利用这个特性,就能很轻易地在分布式环境中举行Master推举了。
乐成创建该节点的客户端地点的呆板就成为了Master。同时,其他没有乐成创建该节点的客户端,都会在该节点上注册一个子节点变动的Watcher,用于监控当前Master呆板是否存活,一旦发现当前的Master挂了,那么其他客户端将会重新举行Master推举。
如许就实现了Master的动态推举。
分布式锁
分布式锁是控制分布式体系之间同步访问共享资源的一种方式。
分布式锁又分为排他锁和共享锁两种。
排他锁
排他锁(ExclusiveLocks,简称X锁),又称为写锁或独占锁。
假如事件T1对数据对象O1加上了排他锁,那么在整个加锁期间,只答应事件T1对O1举行读取和更新操纵,其他任何事件都不能在对这个数据对象举行任何范例的操纵(不能再对该对象加锁),直到T1开释了排他锁。
可以看出,排他锁的核心是怎样包管当前只有一个事件得到锁,而且锁被开释后,全部正在等待获取锁的事件都可以或许被关照到。
怎样利用ZooKeeper实现排他锁?
界说锁
ZooKeeper上的一个ZNode可以表现一个锁。比方/exclusive_lock/lock节点就可以被界说为一个锁。
得到锁
如上所说,把ZooKeeper上的一个ZNode看作是一个锁,得到锁就通过创建ZNode的方式来实现。全部客户端都去/exclusivelock节点下创建临时子节点/exclusivelock/lock。ZooKeeper会包管在全部客户端中,终极只有一个客户端可以或许创建乐成,那么就可以以为该客户端得到了锁。同时,全部没有获取到锁的客户端就必要到/exclusive_lock节点上注册一个子节点变动的Watcher监听,以便及时监听到lock节点的变动环境。
开释锁
由于/exclusive_lock/lock是一个临时节点,因此在以下两种环境下,都有大概开释锁。
当前得到锁的客户端呆板发生宕机或重启,那么该临时节点就会被删除,开释锁。
正常实行完业务逻辑后,客户端就会主动将本身创建的临时节点删除,开释锁。
无论在什么环境下移除了lock节点,ZooKeeper都会关照全部在/exclusive_lock节点上注册了节点变动Watcher监听的客户端。这些客户端在吸取到关照后,再次重新发起分布式锁获取,即重复『获取锁』过程。
共享锁
共享锁(SharedLocks,简称S锁),又称为读锁。假如事件T1对数据对象O1加上了共享锁,那么T1只能对O1举行读操纵,其他事件也能同时对O1加共享锁(不能是排他锁),直到O1上的全部共享锁都开释后O1才华被加排他锁。
总结:可以多个事件同时得到一个对象的共享锁(同时读),有共享锁就不能再加排他锁(由于排他锁是写锁)
ZooKeeper在大型分布式体系中的应用
前面已经先容了ZooKeeper的典范应用场景。本节将以常见的大数据产物Hadoop和HBase为例来先容ZooKeeper在此中的应用,资助各人更好地明白ZooKeeper的分布式应用场景。
ZooKeeper在Hadoop中的应用
在Hadoop中,ZooKeeper重要用于实现HA(HiveAvailability),包罗HDFS的NamaNode和YARN的ResourceManager的HA。同时,在YARN中,ZooKeepr还用来存储应用的运行状态。HDFS的NamaNode和YARN的ResourceManager利用ZooKeepr实现HA的原理是一样的,以是本节以YARN为例来先容。
从上图可以看出,YARN重要由ResourceManager(RM)、NodeManager(NM)、ApplicationMaster(AM)和Container四部分构成。此中最核心的就是ResourceManager。
ResourceManager负责集群中全部资源的同一管理和分配,同时吸取来自各个节点(NodeManager)的资源报告信息,并把这些信息按照肯定的战略分配给各个应用程序(ApplicationManager),其内部维护了各个应用程序的ApplicationMaster信息、NodeManager信息以及资源利用信息等。
为了实现HA,必须有多个ResourceManager并存(一样平常就两个),而且只有一个ResourceManager处于Active状态,其他的则处于Standby状态,当Active节点无法正常工作(如呆板宕机或重启)时,处于Standby的就会通过竞争推举产生新的Active节点。
主备切换
下面我们就来看看YARN是怎样实现多个ResourceManager之间的主备切换的。
创建锁节点在ZooKeeper上会有一个/yarn-leader-election/appcluster-yarn的锁节点,全部的ResourceManager在启动的时间,都会去竞争写一个Lock子节点:/yarn-leader-election/appcluster-yarn/ActiveBreadCrumb,该节点是临时节点。ZooKeepr可以或许为我们包管终极只有一个ResourceManager可以或许创建乐成。创建乐成的谁人ResourceManager就切换为Active状态,没有乐成的那些ResourceManager则切换为Standby状态。
可以看到此时集群中ResourceManager2为Active。
注册Watcher监听全部Standby状态的ResourceManager都会向/yarn-leader-election/appcluster-yarn/ActiveBreadCrumb节点注册一个节点变动的Watcher监听,利用临时节点的特性,可以或许快速感知到Active状态的ResourceManager的运行环境。
主备切换当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信息、DelegationToken及VersionInformation等。必要留意的是,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中的应用重要有:
HDFS中NameNode的HA和YARN中ResourceManager的HA。
存储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在这里担负起了分布式集群中相互关照和信息长期化的脚色。
小结:
以上就是一些HBase中依靠ZooKeeper完因素布式和谐功能的典范场景。但究竟上,HBase对ZooKeepr的依靠还不止这些,比如HMaster还依靠ZooKeeper来完成Table的enable/disable状态记录,以及HBase中险些全部的元数据存储都是放在ZooKeeper上的。
由于ZooKeeper出色的分布式和谐本领及精良的关照机制,HBase在各版本的演进过程中越来越多地增长了ZooKeeper的应用场景,从趋势上来看两者的交集越来越多。HBase中全部对ZooKeeper的操纵都封装在了org.apache.hadoop.hbase.zookeeper这个包中,感爱好的同砚可以自行研究。
36大数据(www.36dsj.com)创建于2013年5月,是中国访问量最大的大数据网站。36大数据(微信号:dashuju36)以独立第三方的角度,为大数据财产生态图谱上的需求商、应用商、服务商、技能办理商等相干公司及从业职员提供环球资讯、商机、案例、技能教程、项目对接、创业投资及专访报道等服务。
End.
转载请注明来自36大数据(36dsj.com):36大数据»ZooKeeper原理及其在Hadoop和HBase中的应用
我要评论