大数据Hadoop组件:zookeeper
随着互联网技术的高速发展,企业的IT架构逐步从集中式向分布式过度,所谓的分布式是指:把一个计算任务分解成若干个计算单元,并且分配到若干不同的计算机中去执行,然后汇总计算结果的过程。
为了保证工作的有序开展。在分布式系统中同样需要设置这么一个协作规范。zookeeper可以很好的帮助我们来实现这个目的。
一.背景介绍
1-1 zookeeper简述
zookeeper实际上是雅虎开发的,用于分布式中一致性处理的框架。最初其作为研发Hadoop时的副产品。由于分布式系统中一致性处理较为困难,其他的分布式系统没有必要费劲重复造轮子,故随后的分布式系统中大量应用了zookeeper,以至于zookeeper成为了各种分布式系统的基础组件,其地位之重要,可想而知。著名的hadoop、kafka、dubbo 都是基于zookeeper而构建。
所以ZooKeeper是一个针对大型分布式系统的可靠协调系统。ZooKeeper是分布式系统中的一个重要组件,它能为HDFS、HBase、MapReduce、YARN、Hive等组件提供重要的功能支撑。在分布式应用中,通常需要ZooKeeper来提供可靠的、可扩展的、分布式的、可配置的协调机制来统一各系统的状态。
1-2 一致性
要想理解zookeeper到底是做啥的,那首先得理解清楚,什么是一致性。
所谓的一致性,举个例子:淘宝后台卖家,在后台上架一件大促的商品,通过服务器A提交到主数据库,假设刚提交后立马就有用户去通过应用服务器B去从数据库查询该商品,就会出现一个现象,卖家已经更新成功了,然而买家却看不到;而经过一段时间后,主数据库的数据同步到了从数据库,买家就能查到了。
假设卖家更新成功之后买家立马就能看到卖家的更新,则称为强一致性;
如果卖家更新成功后买家不能看到卖家更新的内容,则称为弱一致性;
而卖家更新成功后,买家经过一段时间最终能看到卖家的更新,则称为最终一致性。
更多的一致性例子可以参考文献2,里面列举了10种一致性的例子,如果要给一致性下个定义,可以是分布式系统中状态或数据保持同步和一致。
所以如何保证在分布式环境下数据的最终一致,这个就是zookeeper需要解决的问题。
二.原理与架构
2-1体系架构
ZooKeeper的体系架构如下图所示:
客户端可以连接到每个Server,每个Server的数据完全相同,每个Follower都和Leader有连接,接受Leader的数据更新操作,Server记录事务日志和快照到持久存储;过半数Server可用,整体服务就可用。Leader只有一个,宕机后会重新选出一个Leader。
2-2 ZooKeeper基本特性
强一致性:Client不论连接到哪个Server,展示给它的都是同一个视图,这是ZooKeeper最重要的功能。
可靠性:具有简单、健壮、良好的性能,如果消息Message被一台服务器接受,那么它将被所有的服务器接受。
实时性:ZooKeeper保证客户端在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。考虑到网络延时等原因,在需要最新数据时,应该在读数据之前调用sync实现。
等待无关(wait-free):慢的或者失效的Client不得干预快速的Client的请求,使得每个Client都能有效的等待。
原子性:更新只能成功或者失败,没有中间状态。
顺序性:包括全局有序和偏序两种。
2-3 ZooKeeper数据模型
ZooKeeper的数据模型基于树型结构的命名空间,与文件系统类似,如下所示:
该数据模型有如下几个特点:
该数据模型是分布式的,数据节点被称为znode,客户端可以连接到每个Server,每个Server的数据完全相同;
znode可以是临时节点也可以是持久性的。对应临时节点,一旦创建znode的客户端与服务器失去联系,这个 znode 也将自动删除,ZooKeeper 的客户端和服务器通信采用长连接方式,每个客户端和服务器通过心跳来保持连接,这个连接状态称为 session,如果 znode 是临时节点,这个session 失效,znode 也就删除了。
znode可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个是 ZooKeeper 的核心特性,ZooKeeper 的很多功能都是基于这个特性实现的,通过这个特性可以实现的功能包括配置的集中管理,集群管理,分布式锁等。
三.zookeeper作用
鼻祖级应用,ResourceManager在整个hadoop中算是单点,为了实现其高可用,分为主备ResourceManager,zookeeper在其中管理整个ResourceManager。
可以想象,主备ResourceManager最初是主RM提供服务,如果一切安好,则zookeeper无用武之地。然而,总归会出现主RM提供不了服务的情况。于是会出现主备切换的情况,而zookeeper正是为主备切换保驾护航。
先来推理一下,主备切换会出现什么问题。传统的主备切换,可以让主备之间维持心跳连接,一旦备机发现主机心跳检测不到了,则自己切换为主机,原来的主机等待救援。这种方式有两个问题,一是由于网络抖动,负载过大等问题,备机检测不到心跳并不能说明主机一定挂了,有可能一定时间后主机或网络恢复,这时候主机并不知道备机已经切换为主机,2台主机互相争用,可能造成脑裂;二是如果一些数据集中在主机上面,则备机切换时由于同步延时势必会损失掉一部分的数据。
如何解决这些问题?早期的方式提供了不少解决方案,比如备机一旦切换为主机,则通过电源控制直接切断主机电源,简单粗暴,但是此刻备机已经是单点,如果主机是因为量撑不住而挂,那备机有可能会重蹈覆辙,最终导致整个服务不可用。
zookeeper又是如何解决这个问题的呢?
zookeeper作为第三方集群参与到主备节点中去,当主备启动时会在zookeeper上竞争创建一个临时锁节点,争用成功者则充当主机,其余备机;
所有备机会监听该临时锁节点,一旦主机与zookeeper间session失效,则临时节点被删除;
一旦临时节点被删除,备机开始重新申请创建临时锁节点,重新争用为主机;
用zookeeper如何解决脑裂?实际上主机争用到节点后通过对根节点做一个ACL权限控制,则其他抢占的机器由于无法更新临时锁节点,只有放弃成为备机。
zookeeper使用了非常简单又现成的方式来解决的这个问题,比起其他方案方便不少,这也是为啥zookeeper流行的原因。说白了,就是把复杂操作封装化精简化。