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

分布式入门之5:paxos

paxos是去中心化协议。目的是在没有中心节点统筹的情况下,通过约定的算法推进流程,使所有节点达到一个一致的状态(批准某个值)
proposer, accepter是其中的主要角色。前者发起投票,后者批准投票。
核心思想是,一旦超过半数的accepter同意某个投票,整个流程结束,批准的那个结果则是最终结果。
 
learner是另一个角色,从各accepter获取到最终的值。实际中,这些角色可能是同一个节点。
 
不同的proposer去争抢一半以上的accepter,直观上会遇到的问题就是死锁。为了解决这个问题, paxos引入轮次的概念来避免死锁。
引入轮次后,需要确保的隐含条件就是: 如果其中一轮已经选举出了一个结果,则后续所有轮次不能再推翻此结果,而必须接受此结果
 
 
协议流程如下:
paxos过程与两阶段提交类似,也分两个阶段。
第一阶段是proposer告诉acceptor,准备提交第n轮,需要保证不接受小于n轮的其他proposer的提案。
第二阶段,则是根据第一阶段acceptor的返回结果,通知acceptor提交某个值。
 
理解算法需要重点关注下面的思想:
  1. 各个proposer之间是一种“互助”角色,而不是“互斥”。一个轮次的prepared消息,会“帮助”整个系统把当前最有希望成为最终值的value提交上去。只有在别人都没有提交过的情况下,才会提交自己的值 。是一个害羞性算法
  2. 各个acceptor上,存储了两个信息,即(已知轮次、已批准值)这一对数据。对应与下图的n与V。下图V_N的意思,则是在第N轮已经批准过一个V值
 
流程如下:
 
 
 
要点为:
只有prepare后收到的“大多数” 全为空时,才能进行提案新的v;否则,只能在收到的大多数中,选择一个 轮次最高被批准的
如果试图在第二阶段提案某个低轮次的值,会被直接Nack打回。 注意,只要有reject与nack,不论是否多数,提交者本轮立即失败。
 
 
如何保证已经在X轮批准了V1后,后续的轮次不再批准其他值?
 
符合以上问题的场景有两种:
  • 第一种是新提一个值推翻旧值,这是不可能的:
X轮批准了V1后,说明X轮中已经有“大多数”acceptor已经记下了V1。而要想再批准其他值, 需要在prepare后收到的“大多数”中全为空,这是不可能的,至少会有一个V1。这论证了是不可能提出新值的。
 
  • 第二种场景是,X轮批准了V1后,只是代表其中有“大多数”中的轮次最高为V1。会不会存在着已被少数派批准的另一个值V2在后续轮次中翻盘,后续轮次将多数派的V1覆盖掉(即V2轮次高于已批准的v1)?
可惜也是不可能的。高轮次少数派V2如果存在,有两种可能:
a. 是在V1得到批准前批准的。那么当V1在第二阶段的提交accept的过程中,会发现有高轮次的值V2已经批准,从而再也不可能取到多数派的通过。(accept中,轮次比较旧的提交直接会被acceptor以Nack打回)。被打回后,老实使用新的轮次来prepare,这时会取到多数派的V2并在后续的accept消息中代为提交。
b. 少数派的V2值是在V1被选举出来后才出现的。这显然不可能,第一种想像场景中已经讨论过了,不可能有新值被提交上来了。
 
 
轮次n:
可见,轮次是个全局的概念,如何保证轮次在整个过程中不同节点轮次不重叠。
只需要定一个 保证递增性与唯一性的规则。如: 时间戳 + 提出提案的次数 + 机器 IP/机器ID。
 
活锁:
虽然paxos以轮次概念的引入解决了死锁,但因为存在着prepare、accept两阶段,有可能出现活锁问题:
如proposer A以prepare 1发起一轮paxos过程,所有acceptor返回null,A准备发送accept(1, Va);
此时proposer B以prepare 2发起又一轮paxos,所有acceptor依然返回null,B准备发送accept(2, Vb);
这时,proposer A以prepare 3继续发起新一轮prepare。。。,循环往复。这就是活锁。
活锁可使用 随机改变轮次n的增长幅度来解决;或者是 指定一个主的proposer,让其来提案。

转载于:https://www.cnblogs.com/qqmomery/p/5525483.html

相关文章:

  • UIScrollView的使用
  • Python学习路程day17
  • python 学习笔记十七 django深入学习二 form,models
  • 深入介绍信号和槽
  • windows下配置python库
  • 个人工作总结03(第二次冲刺)
  • Centos7下Rinetd安装与应用
  • Python3 捕捉异常
  • GCD 和Timer
  • iOS开发UI篇—使用xib自定义UItableviewcell实现一个简单的团购应用界面布局
  • 如何设置电脑的固定IP地址
  • 优质博士的养成之道——对话2015微软学者奖学金获得者
  • 小凡带你搭建本地的光盘yum源
  • Retrofit get post query filed FiledMap
  • ActiveMQ集群应用
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • [译]如何构建服务器端web组件,为何要构建?
  • 10个最佳ES6特性 ES7与ES8的特性
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • CSS实用技巧干货
  • If…else
  • MySQL主从复制读写分离及奇怪的问题
  • Promise面试题,控制异步流程
  • Python学习之路13-记分
  • vue-cli在webpack的配置文件探究
  • 翻译:Hystrix - How To Use
  • 使用Envoy 作Sidecar Proxy的微服务模式-4.Prometheus的指标收集
  • 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用 ...
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • #1014 : Trie树
  • #每天一道面试题# 什么是MySQL的回表查询
  • $ git push -u origin master 推送到远程库出错
  • $().each和$.each的区别
  • (java)关于Thread的挂起和恢复
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (论文阅读40-45)图像描述1
  • (四)图像的%2线性拉伸
  • (转)关于多人操作数据的处理策略
  • .a文件和.so文件
  • .htaccess配置常用技巧
  • .net core 6 redis操作类
  • .NET 分布式技术比较
  • .NET学习全景图
  • @JsonSerialize注解的使用
  • @synthesize和@dynamic分别有什么作用?
  • [].slice.call()将类数组转化为真正的数组
  • [20150629]简单的加密连接.txt
  • [2021ICPC济南 L] Strange Series (Bell 数 多项式exp)
  • [Apio2012]dispatching 左偏树
  • [AutoSar]状态管理(五)Dcm与BswM、EcuM的复位实现
  • [BJDCTF2020]The mystery of ip
  • [Design Pattern] 工厂方法模式
  • [iOS]随机生成UUID通用唯一识别码
  • [leetcode 双指针]