ZooKeeper主要用来解决分布式应用场景中存在的一些问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置管理等。

它支持Standalone模式和分布式模式,在分布式模式下,能够为分布式应用提供高性能和可靠地协调服务,而且使用ZooKeeper可以大大简化分布式协调服务的实现,为开发分布式应用极大地降低了成本。

总体架构

ZooKeeper分布式协调服务框架的总体架构,如图所示:

ZooKeeper集群由一组Server节点组成,这一组Server节点中存在一个角色为Leader的节点,其他节点都为Follower。

  • 写请求:写请求会序列化,每个写请求转发给leader通过ZAB协议达到一致性和顺序性(所有节点更新顺序一致)。
  • 读请求:与chubby不同,chubby所有读写请求必须转发给leader,在zookeeper中,所有的server(leader和follower)都可以响应读请求。这样会带来不一致的问题,zab协议还没有把写消息同步到所有节点上。zookeeper可以通过sync调用(怎么实现的?)强制同步。
  • zxid编号:每次读写,zookeeper都会返回一个zxid编号,zookeeper保证返回的数据不会比客户端传过来的zxid编号更新
  • 模糊快照和日志:zookeeper周期性地将内存中的数据保存在磁盘中形成模糊快照(模糊的含义是不一定是最新的),zookeeper将更新操作都会先写入磁盘。zookeeper保证更新操作都是“幂等的”,所以可以通过模糊快照和日志恢复内存数据。

数据模型

zookeeper通过树形命名空间来进行整个系统的协调,其中的每个节点称为znode,znode有两种持久节点和临时节点。临时节点和会话绑定,会话下线临时节点删除(心跳监控是否宕机)

zookeeper的全部数据都保存在内存中,以此来实现高吞吐,低延迟。

API

//创建节点,flag可以指定递增,临时节点
string create(path, data, acl, flags) //删除节点
void delete(path, expectedVerstion) //改
stat setData(path, data, expectedVersion) //查
(data, stat) getData(path, watch) //存在
stat exist(path, watch) //获取孩子节点
String[] getChildren(path, watch) //同步
void sync(path)

所有有关查的api(3个),可以设置监视器,状态发生变化可以通知

主要功能

领导者选举

在一个特定的目录下,创建一个leader临时节点。热备机周期性地检查这个节点是否存在,如果不存在,就尝试在这个目录下创建leader节点,升级为leader。

(data, stat) = zookeeper.get(handle, "/services/myservice/leader",true);
if(stat == none)
path = zookeeper.create(handle, "/services/myservice/leader", 临时节点)
if(path = none)//失败,获取当前leader
(data, stat) = zookeeper.get(handle, "/services/myservice/leader",true);
else
成功,自己是leader

配置管理(pub-sub服务)

创建特定的节点,用于管理集群的配置信息。所有客户端看见的都是一致的内容,并且可以设置watch在节点内容变更的时候通知客户端。

注意:不要使用zookeeper同步大块数据,进行会急剧下降。会走一致性协议同步,写磁盘,然后在反应在内存中。

成员管理

成员管理的目的就是,集群内某个节点宕机或者新加入节点,zookeeper可以及时感知。实现方式是为每台机器创建临时节点,临时节点和会话绑定。同时,监控客户端可以通过getChildren设置watch,临时节点有变更可以及时通知。

任务分配

  1. 新任务到来:在tasks目录下创建任务节点
  2. 任务分配:监控进程感知到tasks目录下的节点变化,触发任务分配。图中task1分配到machine1的目录下,代表task1分配给machine1
  3. 任务执行:machine1发现自己目录下的任务,执行该任务。结束后删除machine1目录下的task1和task目录下的task1。

锁服务

创建互斥锁

  1. 在l目录下,创建以lock为前缀的递增临时节点,返回节点编号
  2. 获取l目录下所有节点信息
  3. 如果刚刚创建的编号是所有节点编号最小的(最先创建节点的),获得锁
  4. 没有获得锁,进入第2步

创建读写锁

创建写锁

  1. 在l目录下,创建以write为前缀的递增临时节点,返回节点编号
  2. 获取l目录下所有节点信息
  3. 如果刚刚创建的编号是所有节点编号最小的(最先创建节点的),获得锁
  4. 没有获得锁,进入第2步

创建读锁

  1. 在l目录下,创建以read为前缀的递增临时节点,返回节点编号
  2. 获取l目录下所有节点信息
  3. 如果刚刚创建的编号比所有write前缀的编号小,获得读锁
  4. 没有获得锁,进入第2步

释放锁

删除临时节点

双向路障同步

任务统一开始

  1. 在路障节点下创建当前任务节点,代表该任务到达路障
  2. 检测路障节点下任务个数是否足够,足够代表可以继续统一执行

任务统一离开

  1. 任务结束后,任务路障节点下的任务节点
  2. 如果路障节点下没有任务节点,代表所有任务已经执行结束

ZAB协议(ZooKeeper Atomic Broadcast原子消息广播协议)

zab协议所有事务请求必须由leader协调,首先leader发起proposal消息,大多数server同意后,然后leader发送commit消息。

zxid编号

  1. 低32位为计数器,客户端每次请求+1
  2. 高32位为epochID,每次选举新leader+1

状态和阶段

  1. Looking:系统刚启动时或者Leader崩溃后正处于选举状态
  2. Following:Follower节点所处的状态,Follower与Leader处于数据同步阶段
  3. Leading:Leader所处状态,当前集群中有一个Leader为主进程

zookeeper主要分为5个阶段,选举,发现,同步,广播

  1. 选举:Looking状态中选举出Leader节点,Leader的lastZXID总是最新的
  2. 发现:Follower节点向准Leader推送FOllOWERINFO,该信息中包含了上一周期的epoch,接受准Leader的NEWLEADER指令,检查newEpoch有效性,准Leader要确保Follower的epoch与ZXID小于或等于自身的
  3. 同步:将Follower与Leader的数据进行同步,由Leader发起同步指令,最总保持集群数据的一致性
  4. 广播:Leader广播Proposal与Commit,Follower接受Proposal与Commit;

选举

zab必须确保选举出来的leader具有最大的zxid(这和raft很像啊)。这里要注意一下,和raft一样,选举可能会出现两种结果:

  1. 上一轮的多数派(此时leader zxid可能不是最大的,需要同步的时候调用trunc)
  2. 上一轮的少数派,leader zxid真的是最大的(但是这个最大的zxid没有提交,在同步阶段提交?)

过程详解:

  1. 每个Follower都向其他节点发送选自身为Leader的Vote投票请求,等待回复;
  2. Follower接受到的Vote如果比自己的ZXID更新时则投票,并更新自身的Vote,否则拒绝投票;
  3. 每个Follower中维护着一个投票记录表,当某个节点收到过半的投票时,结束投票并把该Follower选为Leader,投票结束;

恢复(发现和同步)

发现

  1. leader生成新的zxid和epoch,接受follower发送来的FOllOWERINFO(含有当前节点的LastZXID)
  2. leader向follower发送NEWLEADER;Leader根据follower发送过来的LastZXID根据数据更新策略向Follower发送更新指令;

同步

  1. SNAP:如果follower数据太老,epoch还在上上一轮,leader将发送快照snap指令给follower同步
  2. DIFF:正常同步阶段
  3. TRUNC:如果Follower是上一轮的少数派(通过对比ztid),发送TRUNC指令让follower丢弃这段数据

广播

进入正常leader提交阶段,产生递增的zxid,接受半数投票后,再提交。

与raft的区别

我觉得zab和raft没有本质的区别,它们唯一的不同点就是如何处理上一个leader的残留日志。

  • raft中,需要本轮iterm有日志提交后,才提交以前的
  • zab中,在同步阶段全部解决

ZooKeeper:架构和算法的更多相关文章

  1. 转载:深入浅出Zookeeper(一) Zookeeper架构及FastLeaderElection机制

    转载至 http://www.jasongj.com/zookeeper/fastleaderelection/: 原创文章,转载请务必将下面这段话置于文章开头处.本文转发自技术世界,原文链接 htt ...

  2. Zookeeper架构、ZAB协议、选举

    转载:深入浅出Zookeeper(一) Zookeeper架构及FastLeaderElection机制  (nice) ZooKeeper学习第六期---ZooKeeper机制架构 一.Zookee ...

  3. Zookeeper架构及FastLeaderElection机制

    原文链接:http://www.jasongj.com/zookeeper/fastleaderelection/ Zookeeper是什么 Zookeeper是一个分布式协调服务,可用于服务发现,分 ...

  4. 读<大数据日知录:架构与算法>有感

    前一段时间, 一个老师建议我能够学学 '大数据' 和 '机器学习', 他说这必定是今后的热点, 学会了, 你就是香饽饽.在此之前, 我对大数据, 机器学习并没有非常深的认识, 总觉得它们是那么的缥缈, ...

  5. 一篇文章带你了解 ZooKeeper 架构

    上一篇文章,我们讲解了 ZooKeeper 入门知识,这篇文章主要讲解下 ZooKeeper 的架构,理解 ZooKeeper 的架构可以帮助我们更好地设计协同服务. 首先我们来看下 ZooKeepe ...

  6. Zookeeper的选举算法和脑裂问题

    ZK介绍 ZK = zookeeper ZK是微服务解决方案中拥有服务注册发现最为核心的环境,是微服务的基石.作为服务注册发现模块,并不是只有ZK一种产品,目前得到行业认可的还有:Eureka.Con ...

  7. ZooKeeper之FastLeaderElection算法详解

    当我们把zookeeper服务启动时,首先需要做的一件事就是leader选举,zookeeper中leader选举的算法有3种,包括LeaderElection算法.AuthFastLeaderEle ...

  8. ZooKeeper架构设计及其应用要点

    问题导读: 1.ZooKeeper的数据模型是什么 ?2.ZooKeeper应用有哪些陷阱 ?3.每个节点(ZNode)中存储的是什么?4.一个ZNode维护了一个状态结构都包含了什么?5.ZNode ...

  9. ZooKeeper架构设计及其应用

    ZooKeeper是一个开源的分布式服务框架,它是Apache Hadoop项目的一个子项目,主要用来解决分布式应用场景中存在的一些问题,如:统一命名服务.状态同步服务.集群管理.分布式应用配置管理等 ...

随机推荐

  1. [mobile]移动端页面没有重新请求时,刷新页面代码

    <input type="hidden" value="yes" id="id_if_reload" /> <script ...

  2. fleet中service之间的依赖关系

    最近有人在topcoder上提出使用fleet在集群上部署service时有时候会发现,当启动依赖于整个集群服务的service时,只会检查那个service所在机器的依赖关系,这样就会造成一些问题, ...

  3. Ubuntu14.04下Pycharm3.4 字体渲染

    在ubuntu下搭建了django的开发环境,搭建过程十分简单,Pycharm的安装更简单,下载tar包解压并执行bin目录下的脚本即可,但是看着那个字体真心不爽.于是开始搜索调教. 1.安装打了渲染 ...

  4. Argument list too long error for rm, cp, mv commands

    Another option is to use find's -delete flag: find . -name "*.pdf" -delete

  5. Team Foundation Server (TFS)集成Flyway,实现数据库的版本管理

    1 概述 在系统开发过程中,我们对软件源代码的版本管理,已经有了比较成熟的解决方案.通过使用TFVC或GIT等源代码管理工具,可以非常方便的对软件代码实现回退.比较.分支合并等版本操作.对于软件依赖的 ...

  6. .net core获取服务器本地IP及Request访问端口

    string str = (Request.HttpContext.Connection.LocalIpAddress.MapToIPv4().ToString() + ":" + ...

  7. WPF 自定义下拉列表

    XAML代码: <Popup x:Name="popupStrategy" StaysOpen="False" PopupAnimation=" ...

  8. 【cocos2d-x 手游研发----界面UI设计】

    简单探讨一下如何在cocos2d-x的游戏引擎里面去制作各做交互UI界面,常见的UI如下: 人物头像,血条值,经验条,技能按钮,以及各种玩家交互的界面按钮:背包,人物属性,门派,等: 类似上面的图示交 ...

  9. PaaS服务之路漫谈(三)

    此文已由作者尧飘海授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. Monolithic架构在产品访问量很大的情况下,有可能常会导致整个产品迭代或升级过程不能按预期进行,或者上 ...

  10. [Uliweb]-URL映射

    URL映射¶ Uliweb使用Werkzeug的Routing来进行URL的处理.当你使用manage.py的makeapp命令生成一个新 的App时,它会自动生成views.py文件,其中会自动从u ...