文档章节

Zookeeper实现分析一

谈吐鱼
 谈吐鱼
发布于 2013/12/22 08:40
字数 1519
阅读 6.5K
收藏 17

行业解决方案、产品招募中!想赚钱就来传!>>>

<h4>最近准备面试,把一年多前阅读zookeeper代码时写的阅读笔记翻出来,顺便整理一下发成博客。</h4> <p></p> <h4>--------------------------------------------------------------------------------------</h4> <h4>1 Zookeeper介绍</h4> <p>Zookeeper是一个分布式的协调服务,为分布式应用程序提供synchronization、configuration maintenance、groups和nameing服务。</p> <p><a href="http://static.oschina.net/uploads/img/201312/22084037_qU1P.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="wps_clip_image-1862" border="0" alt="wps_clip_image-1862" src="http://static.oschina.net/uploads/img/201312/22084037_UcOG.png" width="519" height="163" /></a></p> <p>Zookeeper是一个有众多服务器节点组成的集群,这些节点中有一个主节点(leader),leader是通过leader selection自动地从服务器节点中选举出来。Zookeeper提供了一个类似于标准文件系统目录结构的hierarchal namespace(层次化的命名空间)。如下图所示,hierarchal namespace中的每一个节点都被称为 znode。Znode是组成hierarchal namespace的基本单位。在源码中对应于类DataNode,其维护着节点用户数据、父节点和子节点集合,以及本节点状态。用户可以在hierarchal namespace中创建znode,将数据保存在znode中,并监听znode的状态变化,Zookeeper会保证client对znode的操作是顺序一致性。</p> <p><a href="http://static.oschina.net/uploads/img/201312/22084037_J36w.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="wps_clip_image-28286" border="0" alt="wps_clip_image-28286" src="http://static.oschina.net/uploads/img/201312/22084037_RZUj.png" width="382" height="220" /></a></p> <h4>2 Zookeeper实现分析</h4> <p>Zookeeper服务器节点的实现可以分成两部分:一部分是处理与客户端交互,实现客户端对zookeeper的hierachal namespace的各种操作。另一部分是作为zab算法(paxos算法的zookeeper实现)的参与者(leader、follower、observer三种角色的其中一种),实现具体的算法逻辑。</p> <p>在这篇博客里,我们只讨论zookeeper服务器如何实现第一个部分功能。</p> <p>Zookeeper服务器的hierachal namespace、znode、客户端与服务器连接、以及客户端可以监听服务器的znode状态的watch机制之间的元数据关系如下图所示:</p> <p><a href="http://static.oschina.net/uploads/img/201312/22084038_XTG7.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201312/22084038_5tqz.png" width="554" height="404" /></a> </p> <p>Zookeeper使用<a href="http://baike.baidu.com/view/1436495.htm">Trie树</a> 来实现了hierachal namespace,由PathTrie这个类来完成。为了实现从路径到znode的映射,zookeeper在内存中维护了一个znode的hashmap,key为znode在hierachal namespace上的路径,value为znode对象,znode在zookeeper源码中由DataNode这个类实现。为了实现client监听znode的状态变化,zookeeper将与客户端的连接和hierachal namespace的节点路径进行映射,WatchManager这个类就是用于维护这个映射关系的,其中NIOServerCnxn是zookeeper服务器与client的一个socket连接;为了监听Znode的目录结构的变化和数据变化,zookeeper使用了两个WatchManager,分别用来监听namespace的目录结构和数据的变化。</p> <p>所有以上这些关系都封装在DateTree这个类中,DateTree的类图如下所示。</p> <p><a href="http://static.oschina.net/uploads/img/201312/22084038_o0nR.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201312/22084039_FRC3.png" width="499" height="543" /></a> </p> <p>在paxos算法中有三种角色,分别是提案者,接受者和学习者。在zookeeper中有三种类型的节点,分别是leader、follower和observer三种类型的节点,分别与paxos的三种角色相对应;需要注意的是zookeeper中还有一个learner的概念,这个learner是paxos中的学习者,leader、follower和observer都是learner(即都是学习者,可以学习提案),但observer节点除了是learner之外没有其他功能,也就是说observer只能学习已经批准的提案,而不会参与到提案的投票过程中。observer这个角色的设定是为了保证提案选举的性能不会随着zookeeper集群规模扩大而降低(参与投票的节点越多,每一次投票花费的事件就越多)。</p> <p>在zookeeper中用LeaderZooKeeperServer,FollowerZooKeeperServer和</p> <p>ObserverZooKeeperServer这三个类来实现三种类型的服务器节点。类图如下所示,为了简单起见没有详细给出成员变量和成员函数。</p> <p><a href="http://static.oschina.net/uploads/img/201312/22084039_xoOy.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201312/22084039_DNAq.png" width="348" height="401" /></a> </p> <p>由于Zookeeper的服务器节点有多种类型,不同类型的服务器节点对client发过来的信令都有不同的处理流程,为了实现最大程度上的代码复用,zookeeper采用了责任链的设计模式来实现各种类型的zookeeper节点。所以在每一个ZookeeperServer上都会维护一个RequestProcessor责任链,来处理各个节点上的逻辑。</p> <h5>2.1 leaderZookeeperServer</h5> <p>Leader要完成以下几个事情:</p> <p>1、接收客户端的request请求</p> <p>2、将会修改同步数据的request请求 转化为proposal,并保存.</p> <p>3、向所有的follower发送proposal。</p> <p>4、接收follower的ack。</p> <p>5、统计收到的ack,如果某一个proposal的ack超过了半数,那么向所有follower发送commit 信令,并向所有observer发送inform信令,执行这个proposal的动作。</p> <p>6、leader自己执行已经被commit的proposal所对应的操作,并回复结果。</p> <p>LeaderZookeeperServer的责任链如下面两图所示:</p> <p><a href="http://static.oschina.net/uploads/img/201312/22084039_ZjgO.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201312/22084039_3Go0.png" width="411" height="354" /></a> </p> <p><a href="http://static.oschina.net/uploads/img/201312/22084040_03MO.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201312/22084040_tHAf.png" width="515" height="554" /></a> </p> <h5>2.2 FollowerZooKeeperServer</h5> <p>Follower:主要负责批准或否决leader提出的proposal。Follower的主要逻辑处理如下:</p> <p>1、 发现leader。</p> <p>2、 建立与leader的连接。</p> <p>3、 向leader注册。(leader activation)</p> <p>4、 与leader进行同步。</p> <p>5、 无限循环</p> <p>---读取从leader处接收到的信令。</p> <p>---处理从leader处接收到的信令。</p> <p>A、 如果是PROPOSAL信令(写请求),将此信令投递到FollowerZooKeeperServer的synProcessor。主要作用是回复leader一个ack。</p> <p>B、 如果是COMMIT信令,将此信令投递到FollowerZooKeeperServer的commitProcessor。最终执行FollowerZooKeeperServer的commit函数。</p> <p>C、 如果是SYNC信令,将此信令投递到FollowerZooKeeperServer的commitProcessor。commitProcessor直接将此信令转发给FinalRequestProcessor,将sync信令带的内容写入持久层。</p> <p>FollowZookeeperServer的责任链如下所示:</p> <p><a href="http://static.oschina.net/uploads/img/201312/22084040_aXKr.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201312/22084040_frJf.png" width="429" height="259" /></a> </p> <p><a href="http://static.oschina.net/uploads/img/201312/22084040_jmip.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201312/22084041_zn2Z.png" width="509" height="598" /></a> </p> <h5>2.3 ObserverZooKeeperServer</h5> <p>observer:学习已经被commit的proposal的结果,然后执行相应的操作。Observer主要处理逻辑:</p> <p>1、 发现leader。</p> <p>2、 连接到leader上,建立TCP连接。</p> <p>3、 与leader进行同步,同步leader上已经被commit的proposal。</p> <p>4、 无限循环,读取接收到得信令,处理信令。</p> <p>1、如果是syn信令,调用<a name="OLE_LINK1"></a><a name="OLE_LINK2">ObserverZooKeeperServer</a>的syn函数,投递到commitProcessor中。</p> <p>2、如果是info信令,同样调用ObserverZooKeeperServer的commit函数,投递到commitProcessor中。</p> <p>OserverZookeeperServer的责任链基本上与follower的相同如下,只是commitProcessor调用的commit函数里的处理不同:</p> <p><a href="http://static.oschina.net/uploads/img/201312/22084041_UJ6J.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201312/22084041_crkg.png" width="393" height="239" /></a> </p> <p><a href="http://static.oschina.net/uploads/img/201312/22084041_u81T.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201312/22084041_35zj.png" width="510" height="591" /></a> </p> <h5>2.4 Zookeeper各节点交互</h5> <p>Zookeeper各个角色的信令交互图:</p> <p>最后画了一张各个zookeeper server的信令交互图</p> <p><a href="http://static.oschina.net/uploads/img/201312/22084042_v6Vr.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://static.oschina.net/uploads/img/201312/22084042_tGiP.png" width="529" height="336" /></a> </p> <p>作者zy,QQ105789990</p>

谈吐鱼
粉丝 37
博文 13
码字总数 41855
作品 0
杭州
程序员
私信 提问
加载中
请先登录后再评论。
用vertx实现高吞吐量的站点计数器

工具:vertx,redis,mongodb,log4j 源代码地址:https://github.com/jianglibo/visitrank 先看架构图: 如果你不熟悉vertx,请先google一下。我这里将vertx当作一个容器,上面所有的圆圈要...

jianglibo
2014/04/03
4K
3
Flappy Bird(安卓版)逆向分析(一)

更改每过一关的增长分数 反编译的步骤就不介绍了,我们直接来看反编译得到的文件夹 方法1:在smali目录下,我们看到org/andengine/,可以知晓游戏是由andengine引擎开发的。打开/res/raw/at...

enimey
2014/03/04
5.9K
18
SQLServer实现split分割字符串到列

网上已有人实现sqlserver的split函数可将字符串分割成行,但是我们习惯了split返回数组或者列表,因此这里对其做一些改动,最终实现也许不尽如意,但是也能解决一些问题。 先贴上某大牛写的s...

cwalet
2014/05/21
9.6K
0
Swift百万线程攻破单例(Singleton)模式

一、不安全的单例实现 在上一篇文章我们给出了单例的设计模式,直接给出了线程安全的实现方法。单例的实现有多种方法,如下面: class SwiftSingleton { } 这段代码的实现,在shared中进行条...

一叶博客
2014/06/20
3.3K
16
beego API开发以及自动化文档

beego API开发以及自动化文档 beego1.3版本已经在上个星期发布了,但是还是有很多人不了解如何来进行开发,也是在一步一步的测试中开发,期间QQ群里面很多人都问我如何开发,我的业余时间实在...

astaxie
2014/06/25
2.7W
22

没有更多内容

加载失败,请刷新页面

加载更多

数据获取的小技巧

在大数据如此火的时代,我们要获取更多数据,就要进行数据采集,过滤,然后再进行使用。比如当我们在进行一个项目并且需要大量真实数据时,就需要通过爬虫去获得,有些爬取额数据还不能直接使用,...

xiaotaomi7
41分钟前
21
0
docker cp 容器和虚拟机间的数据拷贝

容器复制到主机 docker cp {container_name}:{source_path} {target_path}#例子: docker cp php:www/php.ini /home/alex/php.ini 主机复制到容器 docker cp {source_path} {container_nam......

关元
50分钟前
25
0
spring boot整合kafaka批量消费

spring boot整合kafaka批量消费: 配置文件: kafka: producer: bootstrap-servers: 127.0.0.1:9092 batch-size: 16785 #一次最多发送数据量 retries: 1 #发送失败后的重复发送次数 buffer-m...

漫步行者
54分钟前
7
0
最新苹果多屏电脑控制技术---ios群控/苹果群控/一键实时同步操作/入门安装步骤以及功能讲解

创联苹果群控是一款通过无线发送命令来操作主控手机来带动全部被控手机,主控手机怎么操作被控手机全部同步进行相同操作,支持一键每台手机输入不一样的文字!无需连接USB数据线、无需XP框架...

osc_bodzcw38
55分钟前
10
0
NOIP模拟赛 编码

题目描述 一个字符串str的p型编码a的定义如下:把str表示成b1个c1,b2个c2…bn个cn,然后将b1,c1,b2,c2,…,bn,cn收尾拼接成的字符串中最短的字符串设为a。例如:字符串122344111可被描述为"1个...

osc_wcs4pa6z
56分钟前
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部