当前位置: 首页 > news >正文

paxos算法_zookeeper为什么弃用paxos而选用zab协议?

专注于Java领域优质技术号,欢迎关注

原文出处: 笨狐狸

之前讨论了paxos算法,把paxos推到一个很高的位置。但是,paxos有没有什么问题呢?实际上,paxos还是有其自身的缺点的:

1. 活锁问题

在base-paxos算法中,不存在leader这样的角色,于是存在这样一种情况,即P1提交了一个proposal n1并且通过了prepare阶段;此时P2提交了一个proposal n2(n2>n1)并且也通过了prepare阶段;P1在commit时因为已经通过了n2而被拒绝;于是P1继续提交一个proposal n3并且通过prepare阶段;巧的是此时P2开始commit了,由于n2

2. 复杂度问题

base-paxos协议中还存在这样那样的问题,于是各种变种paxos出现了,比如为了解决活锁问题,出现了multi-paxos;为了解决通信次数较多的问题,出现了fast-paxos;为了尽量减少冲突,出现了epaxos。可以看到,工业级实现需要考虑更多的方面,诸如性能,异常等等。这也是为啥许多分布式的一致性框架并非真正基于paxos来实现的原因。

3. 全序问题

对于paxos算法来说,不能保证两次提交最终的顺序,而zookeeper需要做到这点。

For high-performance, it is important that ZooKeeper can handle multiple outstanding state changes requested by the client and that a prefix of operations submitted concurrently are committed according to FIFO order.

基于以上这些原因,zookeeper并没有用paxos作为自己实现的协议,取而代之采用了一种称为zab的协议,全称是zookeeper atomic broadcast。下面简单介绍一下zab协议。

上面说过了,paxos存在活锁问题,为了解决活锁问题,zab引入了leader,但是单leader就是赤裸裸的单点问题,如何解决这个单点呢?

paxos采用的方法是leader选举(没有采用主备,因为主备过于固定,不够分布式)。leader选举就必然出现状态不一致的情况,于是就有着同步这样的过程。

zab协议分为4个阶段,即阶段0为leader选举,阶段1为发现,阶段2为同步,阶段3为广播。而实际实现时将发现及同步阶段合并为一个恢复阶段。

9d44ff7f662d0acf2cc692bb1c75bc9d.png
51a8e5eb6e5362bdfc55cf1f7060d974.png

0. leader选举阶段。当集群中没有leader或者其他人感受不到leader时会进入这一阶段,这一阶段的主要目的是选出zxid最大的节点作为准leader。

1. recovery阶段。本阶段的主要目的是根据准leader的情况将数据同步到其他节点。同步完成后准leader变为leader。

2. broadcast阶段。本阶段的主要目的是leader收到请求,并将请求转为proposal,其他节点根据协议进行批准或通过。broadcast阶段事实上就是一个两阶段提交的简化版。其所有过程都跟两阶段提交一致,唯一不一致的是不能做事务的回滚。

广播的过程实际上类似于二阶段提交,但是如果实现完整的两阶段提交,那就解决了一致性问题,没必要发明新协议了,所以zab实际上抛弃了两阶段提交的事务回滚,于是一台follower只能回复ACK或者干脆就不回复了,leader只要收到过半的机器回复即通过proposal。但是这样的设计就存在很多问题,比如如果一个follower因为网络问题从头到尾一直没收到过leader的proposal,后续的询问刚好落到这台follower上该如何处理?比如leader第一阶段收到了所有follower的ACK后提交,然后通知其他follower提交,这时自己挂了该如何处理?于是诞生了崩溃恢复阶段,旨在对各种不一致情况做出恢复和处理。

对于选举和恢复阶段。zab算法需要确保两件事。

1. 已经处理过的proposal不能被丢弃

发生场景:leader发送了proposal,follower1和follower2回复了ACK给leader,leader向所有follower发送commit请求并commit自身,此时leader挂了。leader已经提交,但是follower尚未提交,这会存在不一致的情况。

确保方式:

a. 重新选举leader时只挑选zxid最大的follower。因为至少半数的follower曾今回复ACK,意味着重新选举时zxid最大的follower应该是当初回复ACK但尚未提交的其中一台。

b. 该follower即准leader,将自身收到prepare但尚未提交的proposal提交

c. 在选举阶段准leader已经能拿到其余follower的所有事务集合,于是准leader根据各个follower的事务执行情况,分别建立队列,先发送prepare请求,再发送commit请求,让所有follower都同步到与leader一样的状态。

通过以上方式,能够确保提交过的proposal不会出现丢弃的情况。

2. 已经丢弃的proposal不能被重复处理

发生场景:leader收到请求,包装为proposal,此时网络挂了或者leader挂了导致其他follower没收到请求,此时进入崩溃恢复阶段,此时其他follower选主并成功之后这个挂了 的leader以follower的身份加入,此时它有一个多余的proposal,与其他节点不一致。

确保方式:

通过zxid的大小能够直接确定。zxid的编码方式为高32位为epoch(即纪元,可以理解为代),低32位为每个proposal顺序递增的数字。每次变换一个leader,则epoch加一,可以理解为改朝换代了,这样,新朝代的zxid必然比旧朝代的zxid大,新代的leader可以要求将旧朝代的proposal清除。

可以考虑一下,如果leader在崩溃恢复阶段就满血复活了,此时集群的情况是什么样的。

相关文章:

  • python中元组怎么存放元素_人生苦短 | Python列表和元组的性能以及存储方式等
  • 前端遍历导致查询数据时间过长_「干货」一文搞懂为什么图数据库比关系型数据库查询更快...
  • 对抗生成网络_如何应用TFGAN快速实践生成对抗网络?
  • debian编译安装python3.8_Debian8 下我想安装个 python3 的 pip,然而各种报错,完全不懂...
  • 用python语言实现人工智能猴子摘香蕉的问题_人工智能 猴子香蕉问题
  • python子类继承_Python:子类可以重载继承的方法吗?
  • python调用opengl_Python之OpenGL笔记(1):窗口工具包GLFW的安装
  • 最长有效括号python_leetcode 032中最长有效括号的Python实现,Leetcode032,python
  • 60多套html5移动端模板_扫盲贴:全网最系统、完整的Web前端和移动APP开发知识...
  • python实现端口转发_python实现超简单端口转发的方法
  • x9此计算机上没有hasp_150马力23方货厢,跑快递快运不妨看看陕汽轩德X9蓝牌轻卡...
  • 贝叶斯思维 统计建模的python_《贝叶斯思维:统计建模的Python学习法》--第3章Estimation(估计)介绍...
  • 手机 调起自带地图 java_安卓11系统再加紧封锁!国内第三方手机应用商店或将全部阵亡?...
  • 串口中断和定时器中断_STM32f103单片机(四)——定时器中断
  • 多个参数变更update_PTOSC在线DDL变更工具使用攻略
  • [译]如何构建服务器端web组件,为何要构建?
  • “大数据应用场景”之隔壁老王(连载四)
  • 08.Android之View事件问题
  • JavaScript创建对象的四种方式
  • JSONP原理
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • node和express搭建代理服务器(源码)
  • PHP 的 SAPI 是个什么东西
  • Spring Boot MyBatis配置多种数据库
  • Spring框架之我见(三)——IOC、AOP
  • Vultr 教程目录
  • 翻译:Hystrix - How To Use
  • 解析 Webpack中import、require、按需加载的执行过程
  • 使用docker-compose进行多节点部署
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 仓管云——企业云erp功能有哪些?
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​Python 3 新特性:类型注解
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • #14vue3生成表单并跳转到外部地址的方式
  • #includecmath
  • #微信小程序:微信小程序常见的配置传值
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (三)docker:Dockerfile构建容器运行jar包
  • (十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
  • (学习日记)2024.01.19
  • (一)eclipse Dynamic web project 工程目录以及文件路径问题
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • .[backups@airmail.cc].faust勒索病毒的最新威胁:如何恢复您的数据?
  • .L0CK3D来袭:如何保护您的数据免受致命攻击
  • .NET Compact Framework 3.5 支持 WCF 的子集
  • .NET Core 通过 Ef Core 操作 Mysql
  • .Net Core和.Net Standard直观理解
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • .netcore 如何获取系统中所有session_如何把百度推广中获取的线索(基木鱼,电话,百度商桥等)同步到企业微信或者企业CRM等企业营销系统中...
  • .net获取当前url各种属性(文件名、参数、域名 等)的方法
  • @property python知乎_Python3基础之:property
  • @RequestBody与@ResponseBody的使用