ZooKeeper:架构和算法
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,临时节点有变更可以及时通知。
任务分配
- 新任务到来:在tasks目录下创建任务节点
- 任务分配:监控进程感知到tasks目录下的节点变化,触发任务分配。图中task1分配到machine1的目录下,代表task1分配给machine1
- 任务执行:machine1发现自己目录下的任务,执行该任务。结束后删除machine1目录下的task1和task目录下的task1。
锁服务
创建互斥锁
- 在l目录下,创建以lock为前缀的递增临时节点,返回节点编号
- 获取l目录下所有节点信息
- 如果刚刚创建的编号是所有节点编号最小的(最先创建节点的),获得锁
- 没有获得锁,进入第2步
创建读写锁
创建写锁
- 在l目录下,创建以write为前缀的递增临时节点,返回节点编号
- 获取l目录下所有节点信息
- 如果刚刚创建的编号是所有节点编号最小的(最先创建节点的),获得锁
- 没有获得锁,进入第2步
创建读锁
- 在l目录下,创建以read为前缀的递增临时节点,返回节点编号
- 获取l目录下所有节点信息
- 如果刚刚创建的编号比所有write前缀的编号小,获得读锁
- 没有获得锁,进入第2步
释放锁
删除临时节点
双向路障同步
任务统一开始
- 在路障节点下创建当前任务节点,代表该任务到达路障
- 检测路障节点下任务个数是否足够,足够代表可以继续统一执行
任务统一离开
- 任务结束后,任务路障节点下的任务节点
- 如果路障节点下没有任务节点,代表所有任务已经执行结束
ZAB协议(ZooKeeper Atomic Broadcast原子消息广播协议)
zab协议所有事务请求必须由leader协调,首先leader发起proposal消息,大多数server同意后,然后leader发送commit消息。
zxid编号
- 低32位为计数器,客户端每次请求+1
- 高32位为epochID,每次选举新leader+1
状态和阶段
- Looking:系统刚启动时或者Leader崩溃后正处于选举状态
- Following:Follower节点所处的状态,Follower与Leader处于数据同步阶段
- Leading:Leader所处状态,当前集群中有一个Leader为主进程
zookeeper主要分为5个阶段,选举,发现,同步,广播
- 选举:Looking状态中选举出Leader节点,Leader的lastZXID总是最新的
- 发现:Follower节点向准Leader推送FOllOWERINFO,该信息中包含了上一周期的epoch,接受准Leader的NEWLEADER指令,检查newEpoch有效性,准Leader要确保Follower的epoch与ZXID小于或等于自身的
- 同步:将Follower与Leader的数据进行同步,由Leader发起同步指令,最总保持集群数据的一致性
- 广播:Leader广播Proposal与Commit,Follower接受Proposal与Commit;
选举
zab必须确保选举出来的leader具有最大的zxid(这和raft很像啊)。这里要注意一下,和raft一样,选举可能会出现两种结果:
- 上一轮的多数派(此时leader zxid可能不是最大的,需要同步的时候调用trunc)
- 上一轮的少数派,leader zxid真的是最大的(但是这个最大的zxid没有提交,在同步阶段提交?)
过程详解:
- 每个Follower都向其他节点发送选自身为Leader的Vote投票请求,等待回复;
- Follower接受到的Vote如果比自己的ZXID更新时则投票,并更新自身的Vote,否则拒绝投票;
- 每个Follower中维护着一个投票记录表,当某个节点收到过半的投票时,结束投票并把该Follower选为Leader,投票结束;
恢复(发现和同步)
发现
- leader生成新的zxid和epoch,接受follower发送来的FOllOWERINFO(含有当前节点的LastZXID)
- leader向follower发送NEWLEADER;Leader根据follower发送过来的LastZXID根据数据更新策略向Follower发送更新指令;
同步
- SNAP:如果follower数据太老,epoch还在上上一轮,leader将发送快照snap指令给follower同步
- DIFF:正常同步阶段
- TRUNC:如果Follower是上一轮的少数派(通过对比ztid),发送TRUNC指令让follower丢弃这段数据
广播
进入正常leader提交阶段,产生递增的zxid,接受半数投票后,再提交。
与raft的区别
我觉得zab和raft没有本质的区别,它们唯一的不同点就是如何处理上一个leader的残留日志。
- raft中,需要本轮iterm有日志提交后,才提交以前的
- zab中,在同步阶段全部解决
ZooKeeper:架构和算法的更多相关文章
- 转载:深入浅出Zookeeper(一) Zookeeper架构及FastLeaderElection机制
转载至 http://www.jasongj.com/zookeeper/fastleaderelection/: 原创文章,转载请务必将下面这段话置于文章开头处.本文转发自技术世界,原文链接 htt ...
- Zookeeper架构、ZAB协议、选举
转载:深入浅出Zookeeper(一) Zookeeper架构及FastLeaderElection机制 (nice) ZooKeeper学习第六期---ZooKeeper机制架构 一.Zookee ...
- Zookeeper架构及FastLeaderElection机制
原文链接:http://www.jasongj.com/zookeeper/fastleaderelection/ Zookeeper是什么 Zookeeper是一个分布式协调服务,可用于服务发现,分 ...
- 读<大数据日知录:架构与算法>有感
前一段时间, 一个老师建议我能够学学 '大数据' 和 '机器学习', 他说这必定是今后的热点, 学会了, 你就是香饽饽.在此之前, 我对大数据, 机器学习并没有非常深的认识, 总觉得它们是那么的缥缈, ...
- 一篇文章带你了解 ZooKeeper 架构
上一篇文章,我们讲解了 ZooKeeper 入门知识,这篇文章主要讲解下 ZooKeeper 的架构,理解 ZooKeeper 的架构可以帮助我们更好地设计协同服务. 首先我们来看下 ZooKeepe ...
- Zookeeper的选举算法和脑裂问题
ZK介绍 ZK = zookeeper ZK是微服务解决方案中拥有服务注册发现最为核心的环境,是微服务的基石.作为服务注册发现模块,并不是只有ZK一种产品,目前得到行业认可的还有:Eureka.Con ...
- ZooKeeper之FastLeaderElection算法详解
当我们把zookeeper服务启动时,首先需要做的一件事就是leader选举,zookeeper中leader选举的算法有3种,包括LeaderElection算法.AuthFastLeaderEle ...
- ZooKeeper架构设计及其应用要点
问题导读: 1.ZooKeeper的数据模型是什么 ?2.ZooKeeper应用有哪些陷阱 ?3.每个节点(ZNode)中存储的是什么?4.一个ZNode维护了一个状态结构都包含了什么?5.ZNode ...
- ZooKeeper架构设计及其应用
ZooKeeper是一个开源的分布式服务框架,它是Apache Hadoop项目的一个子项目,主要用来解决分布式应用场景中存在的一些问题,如:统一命名服务.状态同步服务.集群管理.分布式应用配置管理等 ...
随机推荐
- 百分之 95% 的程序员不知道 Trending 是什么。
前言如果学习到的知识不成体系,那么遇到问题时就会非常难解决.常有人问你从哪里了解新技术怎么判断其发展趋势的,除了关注 Hacker News 以及庞大的 Awesome 还有没有其它方式?有啊当然是每 ...
- Replication--查看未分发命令和预估所需时间
当复制有延迟时,我们可以使用复制监视器来查看各订阅的未分发命令书和预估所需时间,如下图: 但是当分发和订阅数比较多的时候,依次查看比较费时,我们可以使用sys.sp_replmonitorsubscr ...
- asp.net使用SpeechSynthesizer类生成语音文件部署到iis遇到的几个坑
首先需要引入命名空间System.Speech.Synthesis,代码如下: using (var speechSyn = new SpeechSynthesizer()) { speechSyn. ...
- 构建NetCore应用框架之实战篇(六):BitAdminCore框架架构小结
本篇承接上篇内容,如果你不小心点击进来,建议从第一篇开始完整阅读,文章内容继承性连贯性. 构建NetCore应用框架之实战篇系列 一.小结 1.前面已经完成框架的第一个功能,本篇做个小结. 2.直接上 ...
- Docker容器的原理与实践(上)
本文来自网易云社区. 虚拟化 是一种资源管理技术,将计算机的各种资源予以抽象.转换后呈现出来, 打破实体结构间的不可切割的障碍,使用户可以比原本更好的方式来应用这些资源. Hypervisor 一种运 ...
- FFmpeg编写的代码
//初始化解封装 av_register_all(); avformat_network_init(); avcodec_register_all(); //封装文件的上下文 ...
- ZZNU 2055(基姆拉尔森计算公式)
题目链接 题意: 比如今天是2017年8月16日,星期三.下一个也是星期三的8月16日发生在2023年. 现在是日期是yyyy-mm-dd,我们希望你求出薛定谔会跳跃到那一年. 题解: emmmm.. ...
- 解决org.hibernate.QueryException illegal attempt to dereference collection 异常错误
今天做项目的时候,有两个实体:款式.品牌两者关系是多对多的关联关系,实现的功能是:通过选择款式,显示出该款式的所有品牌.HQL语句如下: 运行时出现这个异常错误:org.hibernate.Query ...
- Windows下安装MySQL详细教程
Windows下安装MySQL详细教程 1.安装包下载 2.安装教程 (1)配置环境变量 (2)生成data文件 (3)安装MySQL (4)启动服务 (5)登录MySQL (6)查询用户密码 (7 ...
- Python小白学习之路(十九)—【文件操作步骤】【文件操作模式】
一.文件操作步骤 step1:打开文件,得到文件句柄并赋值给一个变量step2:通过句柄对文件进行操作step3:关闭文件 举例: a = open('hello world', 'r', encod ...