数据产品经理有必要了解的Zookeeper

       本文是Hadoop生态体系组件之Zookeeper的学习总结性文章。因本人非技术出身,所学均来源于网络,难免有不严谨甚至错误之处,恳请大家指正。

       在上篇关于YARN的文章中我们提到了ZooKeeper,当时只是简单的介绍了他是为了解决master/slave架构中的高可用问题的,并没做过多讲解。那么此篇文章我将详细的讲解下ZooKeeper,包括其产生的背景、应用场景以及部分原理以及其在Hadoop生态系统中扮演了什么样的角色。

什么是Zookeeper

       ZooKeeper是一个分布式的,开源的分布式应用程序协调服务(服务协调是分布式系统的基础,它能够解决leader选举、服务发现、分布式队列、分布式锁等常见的分布式问题)

Zookeeper产生的背景

       Zookeeper源自雅虎研究所。当时,研究人员发现雅虎系统中的许多系统很大程度上依赖于类似的分布式协作系统,但这些系统都存在分布式单点故障问题。因此,雅虎的开发人员开发了一个通用的分布式协调框架来解决这个问题,这就是大名鼎鼎的Zookeeper。

Zookeeper存在的意义

       在分布式系统中,服务(或组件)之间的协调是非常重要的,它构成了分布式系统的基础。而ZooKeeper通常在分布式系统中担任协调者的角色,比如leader选举、负载均衡、服务发现、分布式队列(帮助我们实现跨进程、跨主机、跨网络的数据共享和数据传递的需求)和分布式锁(为了防止分布式系统中的多个进程之间相互干扰,需要一种分布式协调技术来对这些进程进行调度,而这个分布式协调技术的核心就是分布式锁)等,接下来以leader选举和负载均衡为例,说明Zookeeper存在的意义及基本职责。


master/slave架构

leader选举:在分布式系统中,常见的一种软件设计架构为master/slave,如上图所示,其中master负责集群管理,slave负责执行具体的任务(比如存储数据、处理数据),如前面的HDFS、YARN等均采用了该架构。这种架构存在一个明显缺陷:master是单点。为了避免master出现故障导致整个集群不可用,常见的优化方式是引入多master,比如双master:active master和standby master,其中active master对外提供服务,而standby master则作为备用master,一直处于“待命”状态,一旦active master出现故障,自己则切换为active master。

kafka消息队列负载均衡

负载均衡:在类似于Kafka(后续文章会讲到)的分布式消息队列中,如上图,生产者将数据写入分布式队列,消费者从分布式消息队列中读取数据进行处理,为了实现该功能,需要从架构上解决以下两个问题:
1)生产者和消费者如何获知最新的消息队列位置?消息队列是分布式的,通常由一组节点构成,这些节点的健康状态是动态变化的,比如某个节点因机器故障变得对外不可用,如何让生产者和消费者动态获知最新的消息队列节点位置是必须要解决的问题。
2)如何让生产者将数据均衡地写入消息队列中各个节点?消息队列提供了一组可存储数据的节点,需让生产者及时了解各个存储节点的负载,以便智能决策将数据均衡地写入这些节点。为了解决以上两个问题,需要引入一个可靠的分布式协调服务,它具备简单的元信息存储和动态获取服务状态等基本功能。通过leader选举和负载均衡两个常见的分布式问题,我们可以了解到,协调服务对于一个分布式系统而言多重要。为了解决服务协调这一类通用问题,ZooKeeper出现了,它将服务协调的职责从分布式系统中独立出来,以减少系统的耦合性和增强扩充性。

Zookeeper在Hadoop体系中扮演的角色

       Hadoop是分布式系统,所以为了可以正常运作则需要有一个分布式协调服务。因此ZooKeeper就被用于提供协调服务的组件存在于Hadoop生态系统中。他可以帮助用户轻易地实现前面提到leader选举、分布式锁、分布式队列等功能。比如在HDFS中的NameNode高可用(leader选举问题)、YARN中的ResourceManager高可用(leader选举问题)、HBase(leader选举与分布式锁等)等。

Zookeeper架构及原理

       如图下图所示,ZooKeeper服务通常由奇数个ZooKeeper实例构成,其中一个实例为leader角色,其他为follower角色。

ZooKeeper基本架构

ZooKeeper读写数据的路径如下:
读路径:任意一个ZooKeeper实例均可为客户端提供读服务。ZooKeeper实例数目越多,读吞吐率越高。
写路径:任意一个ZooKeeeper实例均可接受客户端的写请求,但需进一步转发给leader协调完成分布式写。ZooKeeper采用了ZAB协议,该协议规定,只要多数ZooKeeper实例写成功,就认为本次写是成功的。这意味着,如果一个集群中存在2N+1个ZooKeeper实例,只要其中N+1个实例写成功,则本次写操作是成功的,从容错性角度看,这种情况下,集群的最大容忍失败实例数目为N。需要注意的是,ZooKeeper实例数目越多,写延迟越高。
       当leader出现故障时,ZooKeeper会通过ZAB协议发起新一轮的leader投票选举,保证集群中始终有一个可用的leader。ZooKeeper中多个实例中的内存数据并不是强一致的,它采用的ZAB协议只能保证,同一时刻至少多数节点中的数据是强一致的。为了让客户端读到最新的数据,需给对应的ZooKeeper实例发送同步指令,强制其与leader同步数据。
       在ZooKeeper集群中,随着ZooKeeper实例数目的增多,读吞吐率升高,但写延迟增加(这是因为Zookeeper实例越多,和Leader的通信通道就越堵塞,而写操作是要和Leader进行通讯的,Leader在更多的实例中选择写任务的执行者的时间也可能更长,因此导致了写延迟变高)。为了解决集群扩展性导致写性能下降的问题,ZooKeeper引入了第三个角色:Observer。

       Observer并不参与投票过程,除此之外,它的功能与follower类似:它可以接入正常的ZooKeeper集群,接收并处理客户端读请求,或将写请求进一步转发给leader处理。由于Observer自身能够保存一份数据提供读服务,因此可通过增加Observer实例数提高系统的读吞吐率。由于Observer不参与投票过程,因此它出现故障并不会影响ZooKeeper集群的可用性。Observer常见应用场景如下(此处没太懂,等以后找人问清楚后再以简单易懂的语言来解释):
(1) 作为数据中心间的桥梁: 由于数据中心之间的确定性通信延迟,将一个ZooKeeper部署到两个数据中心会误报网络故障和网络分区导致ZooKeeper不稳定。然而,如果将整个ZooKeeper集群部署到单独一个集群中,另一个集群只部署Observer,则可轻易地解决网络分区问题
(2)作为消息总线:可将ZooKeeper作为一个可靠的消息总线使用,Observer作为一种天然的可插拔组件能够动态接入ZooKeeper集群,通过内置的发布订阅机制近实时获取新的消息。

Zookeeper应用案例

1.leader选举
       在Hadoop生态系统中,HBase、YARN和HDFS等系统,采用了类似的机制解决leader选举问题,因前面提到过就略过啦!
2. 分布式队列
       在分布式计算系统中,常见的做法是,用户将作业提交给系统的Master,并由Master将之分解成子任务后,调度给各个Worker执行。该方法存在一个问题:Master维护了所有作业和Worker信息,一旦Master出现故障,则整个集群不可用。为了避免Master维护过多状态(这里的状态可以简单的理解成任务的信息,包括需要做什么,做了什么,还需要做什么这种信息),一种改进方式是将所有信息保存到ZooKeeper上,进而让Master变得无状态,这使得leader选举过程更加容易。如下图

ZK的分布式队列

       该方案的关键是借助ZooKeeper实现一个分布式队列,并借助ZooKeeper自带的特性,维护作业提交顺序、作业优先级、各节点(Worker)负载情况等。借助ZooKeeper自动编号特性,可轻易实现一个简易的FIFO(First In First Out)队列,在这个队列中,编号小的作业总是先于编号大的作业提交。
3. 负载均衡
       分布式系统很容易通过ZooKeeper实现负载均衡,典型的应用场景是分布式消息队列。在Kafka中,各个Broker和Consumer均会向ZooKeeper注册,保存自己的相关信息,组件之间可动态获取对方的信息。(后续会专门讲Kafka)
4. 配置管理
       配置管理模块是很多分布式系统的基础,它的主要功能是将用户更新的配置文件实时同步到各个节点的服务上,以便它们近似实时的加载这些配置(我曾经负责过类似的分布式配置平台,类似于阿里云的ACM,有兴趣的朋友可以去看他们的官方文档),典型架构如下图所示:

基于ZooKeeper的配置系统

配置管理模块的工作流程如下:
1)服务启动后,ConfigFetcher模块与ZooKeeper服务通信,读取znode节点/serviceA/conf中保存的配置数据,并向该znode注册一个watcher以监听其数据的改动。
2)用户通过ConfigUpdater动态修改znode节点/serviceA/conf中的数据。
3)各个服务收到配置数据变动通知,读取新的配置数据。

参考资料:《大数据技术体系详解:原理、架构与实践》 作者:董西成
这本书写的真的太赞了,我个人感觉也很适合技术基础一般的新手去读!再次感谢作者提供了这么好的书!

你可能感兴趣的:(数据产品经理有必要了解的Zookeeper)