分布式服务框架Zookeeper介绍、原理及应用

Zookeeper简介

Zookeeper 分布式服务框架是 Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等等。

Zookeeper基本概念

zk角色

Zookeeper中的角色主要有以下三类,如下表所示:


zookeeper角色

zk service网络结构

Zookeeper的工作集群可以简单分成两类,一个是Leader,唯一一个,其余的都是follower,如何确定Leader是通过内部选举确定的。


zookeeper服务
  1. Leader和各个follower是互相通信的,对于zk系统的数据都是保存在内存里面的,同样也会备份一份在磁盘上。
      对于每个zk节点而言,可以看做每个zk节点的命名空间是一样的,也就是有同样的数据。(可查看下面的树结构)
  • 如果Leader挂了,zk集群会重新选举,在毫秒级别就会重新选举出一个Leaer。
  • 集群中除非有一半以上的zk节点挂了,zk service才不可用。

zk命名空间结构

Zookeeper的命名空间就是zk应用的文件系统,它和linux的文件系统很像,也是树状,这样就可以确定每个路径都是唯一的,对于命名空间的操作必须都是绝对路径操作。与linux文件系统不同的是,linux文件系统有目录和文件的区别,而zk统一叫做znode,一个znode节点可以包含子znode,同时也可以包含数据。


zookeeper树结构

提示:
比如/Nginx/conf,/是一个znode,/Nginx是/的子znode,/Nginx还可以包含数据,数据内容就是所有安装Nginx的机器IP,/Nginx/conf是/Nginx子znode,它也可以包含内容,数据就是Nginx的配置文件内容。在应用中,我们可以通过这样一个路径就可以获得所有安装Nginx的机器IP列表,还可以获得这些机器上Nginx的配置文件。

zk读写数据

zookeeper读写数据
  • 写数据,但一个客户端进行写数据请求时,会指定zk集群中节点,如果是follower接收到写请求,就会把请求转发给Leader,Leader通过内部的Zab协议进行原子广播,直到所有zk节点都成功写了数据后(内存同步以及磁盘更新),这次写请求算是完成,然后zk service就会给client发回响应
  • 读数据,因为集群中所有的zk节点都呈现一个同样的命名空间视图(就是结构数据),上面的写请求已经保证了写一次数据必须保证集群所有的zk节点都是同步命名空间的,所以读的时候可以在任意一台zk节点上

ps:其实写数据的时候不是要保证所有zk节点都写完才响应,而是保证一半以上的节点写完了就把这次变更更新到内存,并且当做最新命名空间的应用。所以在读数据的时候可能会读到不是最新的zk节点,这时候只能通过sync()解决。这里先不考虑了,假设整个zk service都是同步meta信息的,后面的文章再讨论。

zk znode类型

Zookeeper中znode的节点创建时候是可以指定类型的,主要有下面几种类型。

  1. PERSISTENT:持久化znode节点,一旦创建这个znode点存储的数据不会主动消失,除非是客户端主动的delete。
    SEQUENCE:顺序增加编号znode节点,比如ClientA去zk service上建立一个znode名字叫做/Nginx/conf,指定了这种类型的节点后zk会创建/Nginx/conf0000000000,ClientB再去创建就是创建/Nginx/conf0000000001,ClientC是创建/Nginx/conf0000000002,以后任意Client来创建这个znode都会得到一个比当前zk命名空间最大znode编号+1的znode,也就说任意一个Client去创建znode都是保证得到的znode是递增的,而且是唯一的。
  • EPHEMERAL:临时znode节点,Client连接到zk service的时候会建立一个session,之后用这个zk连接实例创建该类型的znode,一旦Client关闭了zk的连接,服务器就会清除session,然后这个session建立的znode节点都会从命名空间消失。总结就是,这个类型的znode的生命周期是和Client建立的连接一样的。比如ClientA创建了一个EPHEMERAL的/Nginx/conf0000000011的znode节点,一旦ClientA的zk连接关闭,这个znode节点就会消失。整个zk service命名空间里就会删除这个znode节点。
  • PERSISTENT|SEQUENTIAL:顺序自动编号的znode节点,这种znoe节点会根据当前已近存在的znode节点编号自动加 1,而且不会随session断开而消失。
  • EPHEMERAL|SEQUENTIAL:临时自动编号节点,znode节点编号会自动增加,但是会随session消失而消失

Zookeeper设计目的

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

Zookeeper工作原理

Zookeeper 的核心是广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。
  Zab协议有两种模式,它们分别是恢复模式(选主)和广播 模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和leader的状态同步以后, 恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。为了保证事务的顺序一致性,zookeeper采用了递增的事务id号 (zxid)来标识事务。所有的提议(proposal)都在被提出的时候加上了zxid。实现中zxid是一个64位的数字,它高32位是epoch用 来标识leader关系是否改变,每次一个leader被选出来,它都会有一个新的epoch,标识当前属于那个leader的统治时期。低32位用于递增计数。

每个Server在工作过程中有三种状态:

  • LOOKING:当前Server不知道leader是谁,正在搜寻。
  • LEADING:当前Server即为选举出来的leader。
  • FOLLOWING:leader已经选举出来,当前Server与之同步。

选主流程

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

  1. 选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server;
  • 选举线程首先向所有Server发起一次询问(包括自己);
  • 选举线程收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中;
  • 收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server;
  • 线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数, 设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。通 过流程分析我们可以得出:要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1,且存活的Server的数目不得少于 n+1.每个Server启动后都会重复以上流程。在恢复模式下,如果是刚从崩溃状态恢复的或者刚启动的server还会从磁盘快照中恢复数据和会话信 息,zk会记录事务日志并定期进行快照,方便在恢复时进行状态恢复。
    选举的具体流程图如下所示:

zk basic paxos选举

fast paxos流程:
  在选举过程中,某Server首先向所有Server提议自己要成为leader,当其它Server收到提议以后,解决epoch和 zxid的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息,重复这个流程,最后一定能选举出Leader。
选举的具体流程图如下所示:

zk fast paxos选举

同步流程

选完leader以后,zk就进入状态同步过程。

  1. leader等待server连接;
  • Follower连接leader,将最大的zxid发送给leader;
  • Leader根据follower的zxid确定同步点;
  • 完成同步后通知follower 已经成为uptodate状态;
  • Follower收到uptodate消息后,又可以重新接受client的请求进行服务了。
    同步的具体流程图如下所示:
zk同步流程

工作流程

Leader工作流程

  1. 恢复数据;
  • 维持与Learner的心跳,接收Learner请求并判断Learner的请求消息类型;
  • Learner的消息类型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根据不同的消息类型,进行不同的处理。

PING 消息是指Learner的心跳信息;
REQUEST消息是Follower发送的提议信息,包括写请求及同步请求;
ACK消息是Follower的对提议 的回复,超过半数的Follower通过,则commit该提议;
REVALIDATE消息是用来延长SESSION有效时间。

Leader的工作流程简图具体如下所示:

Leader工作流程

Follower工作流程

Follower主要有四个功能:

  1. 向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);
  • 接收Leader消息并进行处理;
  • 接收Client的请求,如果为写请求,发送给Leader进行投票;
  • 返回Client结果。
    Follower的消息循环处理如下几种来自Leader的消息:
  1. PING消息: 心跳消息;
  • PROPOSAL消息:Leader发起的提案,要求Follower投票;
  • COMMIT消息:服务器端最新一次提案的信息;
  • UPTODATE消息:表明同步完成;
  • REVALIDATE消息:根据Leader的REVALIDATE结果,关闭待revalidate的session还是允许其接受消息;
  • SYNC消息:返回SYNC结果到客户端,这个消息最初由客户端发起,用来强制得到最新的更新。
    Follower的工作流程简图具体如下所示:
Follower的工作流程

应用篇

分布式系统的运行是很复杂的,因为涉及到了网络通信还有节点失效等不可控的情况。下面介绍在最传统的master-workers模型,主要可以会遇到什么问题,传统方法是怎么解决以及怎么用zookeeper解决。

Master节点管理

集群当中最重要的是Master,所以一般都会设置一台Master的Backup。
Backup会定期向Master获取Meta信息并且检测Master的存活性,一旦Master挂了,Backup立马启动,接替Master的工作自己成为Master,分布式的情况多种多样,因为涉及到了网络通信的抖动,针对下面的情况:

  1. Backup检测Master存活性传统的就是定期发包,一旦一定时间段内没有收到响应就判定Master Down了,于是Backup就启动,如果Master其实是没有down,Backup收不到响应或者收到响应延迟的原因是因为网络阻塞的问题呢?Backup也启动了,这时候集群里就有了两个Master,很有可能部分workers汇报给Master,另一部分workers汇报给后来启动的Backup,这下子服务就全乱了。
  • Backup是定期同步Master中的meta信息,所以总是滞后的,一旦Master挂了,Backup的信息必然是老的,很有可能会影响集群运行状态。
    解决问题:
    Master节点高可用,并且保证唯一。
    Meta信息的及时同步。
    ** Zookeeper Master选举 **
      Zookeeper会分配给注册到它上面的客户端一个编号,并且zk自己会保证这个编号的唯一性和递增性,N多机器中只需选出编号最小的Client作为Master就行,并且保证这些机器的都维护一个一样的meta信息视图,一旦Master挂了,那么这N机器中编号最小的胜任Master,Meta信息是一致的。

集群worker管理

集群中的worker挂了是很可能的,一旦worker A挂了,如果存在其余的workers互相之间需要通信,那么workers必须尽快更新自己的hosts列表,把挂了的worker剔除,从而不在和它通信,而Master要做的是把挂了worker上的作业调度到其他的worker上。同样的,这台worker重新恢复正常了,要通知其他的workers更新hosts列表。传统的作法都是有专门的监控系统,通过不断去发心跳包(比如ping)来发现worker是否alive,缺陷就是及时性问题,不能应用于在线率要求较高的场景
解决问题:
集群worker监控。
** Zookeeper监控集群 **
  利用zookeeper建立znode的强一致性,可以用于那种对集群中机器状态,机器在线率有较高要求的场景,能够快速对集群中机器变化作出响应。

分布式锁

在一台机器上要多个进程或者多个线程操作同一资源比较简单,因为可以有大量的状态信息或者日志信息提供保证,比如两个A和B进程同时写一个文件,加锁就可以实现。但是分布式系统怎么办?需要一个三方的分配锁的机制,几百台worker都对同一个网络中的文件写操作,怎么协同?还有怎么保证高效的运行?
解决问题:
高效分布式的分布式锁
Zookeeper分布式锁
  分布式锁主要得益于ZooKeeper为我们保证了数据的强一致性,zookeeper的znode节点创建的唯一性和递增性能保证所有来抢锁的worker的原子性。

配置文件管理

集群中配置文件的更新和同步是很频繁的,传统的配置文件分发都是需要把配置文件数据分发到每台worker上,然后进行worker的reload,这种方式是最笨的方式,结构很难维护,因为如果集群当中有可能很多种应用的配置文件要同步,而且效率很低,集群规模一大负载很高。还有一种就是每次更新把配置文件单独保存到一个数据库里面,然后worker端定期pull数据,这种方式就是数据及时性得不到同步。
解决问题:
统一配置文件分发并且及时让worker生效
Zookeeper发布与订阅模型
  发布与订阅模型,即所谓的配置中心,顾名思义就是发布者将数据发布到ZK节点上,供订阅者动态获取数据,实现配置信息的集中式管理和动态更新。例如全局的配置信息,服务式服务框架的服务地址列表等就非常适合使用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,423评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,339评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,241评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,503评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,824评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,262评论 1 207
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,615评论 2 309
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,337评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,989评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,300评论 2 240
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,829评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,193评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,753评论 3 230
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,970评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,708评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,295评论 2 267
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,207评论 2 258

推荐阅读更多精彩内容