讲一个关于paxos的故事...
先讲一个故事。
从前,在国王Leslie Lamport的统治下,有个黑暗的希腊城邦叫paxos。城邦里有3类人,
- 决策者
- 提议者
- 群众
虽然这是一个黑暗的城邦但是很民主,按照议会民主制的政治模式制订法律,群众有什么建议和意见都可以写提案交给提议者,提议者会把提案交给决策者来决策,决策者有奇数个,为什么要奇数个?很简单因为决策的方式很无脑,少数服从多数。最后决策者把刚出炉的决策昭告天下,群众得知决策结果。
等一下,那哪里黑暗呢?问题就出在“提议者会把提案交给决策者来决策”,那么多提案决策者先决策谁的?谁给的钱多就决策谁的。
那这样会有几个问题,决策者那么多,怎么保证最后决策的是同一个提案,以及怎么保证拿到所有提议者中最高的报价。
聪明又贪婪的决策者想到了一个办法:分两阶段报价
第一阶段
- 决策者接受所有比他当前持有报价高的报价,且不会通知之前报价的人
- 提议者给所有决策者报价,若有人比自己报价高就加价,有半数以上决策者接受自己报价就停止报价。
第一阶段结束的状态
每个提议者都觉得有半数以上的大佬接受了自己的提案,很开心。而决策者集团此刻的状态是一致的,半数以上同意的提案只有一个,这个就是报价最高的(因为高的总是可以覆盖低的),具体是谁提的who care,一致就行。
第二阶段
提议者去找收过自己钱的大佬签合同,这里有3种情况:
- 大佬都收了别人更高的价,回去拿钱继续贿赂,回到第一阶段重新升级;
- 大佬收到的最高报价是自己的,美滋滋,半数以上成功签合同,提案成功;
- 提议者回去拿钱回来继续贿赂的时候发现合同已经被签了且半数以上都签了这个提案,不干了,赶快把自己的提案换成已经签了的提案,再去提给所有大佬,看看能不能分一杯羹遇见还没签的大佬。
第二阶段结束的状态
所有提议者手头的提案都是一样的,因为有“赶快把自己的提案换成已经签了的提案”这一步;决策者集团所有成员最终接受的提案是一样的。
好的目的已经达到了,把这个提案昭告天下,让所有群众知道这件事。
故事说完了,用正确的姿势再简单介绍下paxos
分布式系统中的节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing)。
paxos作为基于消息传递通信模型的分布式系统,不可避免的会发生以下错误:进程可能会慢、被杀死或者重启,消息可能会延迟、丢失、重复,在基础 Paxos 场景中,先不考虑可能出现消息篡改即拜占庭错误的情况。
Paxos算法解决的问题是在一个可能发生上述异常的分布式系统中如何就某个值达成一致,保证不论发生以上任何异常,都不会破坏决议的一致性。一个典型的场景是,在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都执行相同的操作序列,那么他们最后能得到一个一致的状态。
为保证每个节点执行相同的命令序列,需要在每一条指令上执行一个“一致性算法”以保证每个节点看到的指令一致。一个通用的一致性算法可以应用在许多场景中,是分布式计算中的重要问题。
Paxos用于解决分布式系统中一致性问题,在一个Paxos过程只批准一个value,只有被prepare的value且被多数Acceptor接受才能被批准,被批准的value才能被learner。在paxos算法中,分为4种角色:
- Acceptor:决策者
- Proposer :提议者
- Client:产生议题者(群众)
- Learner:最终决策学习者(群众)
阶段一:
- Proposer向半数以上的Acceptor发送Prepare请求并附上编号N。
- 若Acceptor收到一个编号为N的Prepare请求,且N大于该Acceptor已经响应过的所有Prepare请求的编号,那么它就会将它已经接受过的编号最大的提案(如果有的话)作为响应反馈给Proposer,同时该Acceptor承诺不再接受任何编号小于N的提案。
- Proposer若没有得到半数以上Acceptor的响应,则编号+1继续发起请求。
阶段二:
- 如果Proposer收到半数以上Acceptor对其发出的编号为N的Prepare请求的响应,那么它就会发送一个[N,提案]Accept请求给半数以上的Acceptor。
- 如果Acceptor收到一个针对编号为N的提案的Accept请求,只要该Acceptor没有对编号大于N的Prepare请求做出过响应,它就接受该提案
看故事的时候不知道大家有没有疑问,我是有的。
决策者Acceptor为什么要多个?
若只有一个acceptor多个proposer,acceptor可以选任意一个提案,很美好,但是有单点问题。
为什么要用“半数以上通过”这个办法来决策?
一个集合不可能同时存在两个半数以上的子集,过半的思想保证提交的value在同一时刻在分布式系统中是唯一的一致的。这种提交方式不管proposer接受到的消息是接受了谁的提议过半,只保证是有提议过半了的。然后再在第二阶段确定这个过半了的提议,让所有节点知道这件事。因此算法如果能保证value被半数acceptor接受,则意味这此时被认定的value是唯一的。
为什么acceptor要接受多个提案?
如果acceptor只能够接受一个提案,则可能发生所有proposer提出的提案都无法达到多数,决策者接收一个就结束了,状态无法一致。
当Proposer有很多个的时候,会有什么问题?
很难有一个proposer收到半数以上的回复,进而不断地执行第一阶段的协议,决策收敛速度慢,很久都不能做出一个决策。
提案为什么要带上编号(即故事中用来贿赂的钱)?
带上编号是为了决策者可以在自身接受到的提案的对比中做出最终的唯一决策。
试想如果按照提案到达时间对比提案,且不说这样就变成了只接收一个第一到达的提案,还可能因为网络原因每个决策者接受到的提案的先后顺序不一样,凉凉。
接着上面的问题,那如果把所有决策者收到的提案汇集起来选出个时间最早的呢?
把提案汇集,这时候肯定需要一个master来做判断,大家有没发现这个master好像就变成了propser,它拿到最早的提案,交给决策者...
其实,这就演变成了paxos的变种协议。
后记
为了避免竞争,加快收敛的速度,有人在算法中加入leader来代替propser,且leader在集群中只有一位,也就是说只有leader有权提议。这时leader会有单点问题,于是又加入了leader选举机制保证健壮性,到目前为止paxos演变的越来越像我下一篇要讲的zab协议了。
为了能讲得更通俗,很多地方讲得不够严谨,见谅,有问题可以提出交流。
其实这篇和zookeeper的关系不太大算是讲zab之前做的一个铺垫吧。
讲一个关于paxos的故事...的更多相关文章
- 一步步做程序优化-讲一个用于OpenACC优化的程序(转载)
一步步做程序优化[1]讲一个用于OpenACC优化的程序 分析下A,B,C为三个矩阵,A为m*n维,B为n*k维,C为m*k维,用A和B来计算C,计算方法是:C = alpha*A*B + beta* ...
- 来来来,有讲一个吐血的故事(matlab)之脚本运行路径是什么
脚本运行路径是什么,这真是太重要!! 重要1:你默认保存的路径 重要2:你访问的相对路径 先放图: 再看一幅图: 我的操作,点击左侧的文件夹,使上框的显示栏路径不一样,再点击运行,发现pwd指示的路径 ...
- 讲一个关于RSA加密算法的故事
有甲乙两个人,甲有两把钥匙,一把叫做甲的公钥,另一把叫做甲的私钥.乙同样有两把钥匙,一把叫做乙的公钥,另一把叫做乙的私钥. 某一天,甲乙成为了好朋友,甲想向乙发送一份保密数据,这份保密数据要求只有甲乙 ...
- 【C#进阶系列】01 CLR的执行模型——一个Hello World的故事
好吧,废话少说,先上一章Hello World图: 我们有了一个Hello world程序,如此之简单,再加上我今天没有用汉字编程o(>﹏<)o,所以一切很简单明了. 故事开始: 编译: ...
- 一个update的小故事
偶尔测试了一段小代码,写个循环 if object_id('tempdb..#TB') is not null drop table #TB go create table #TB ( ID int ...
- 第一讲 一个简单的Qt程序分析
本文概要:通过一个简单的Qt程序来介绍Qt程序编写的基本框架与一些Qt程序中常见的概念 #include <QApplication> #include <QPushButton&g ...
- 讲一个使用jquery-slick旋转木马效果插件案例
效果展示连接 http://www.jqcool.net/demo/201405/jquery-slick/ 今天刚接触这个插件,被这插件搞的大脑风暴了 所以来记录一下使用方法 首先注意一点 不特别标 ...
- python如何讲一个文件中的图片分到两个
最近在做一个图像分类的比赛,作为初次接触深度学习的菜鸟,上手了keras.说实话,除了keras教程,中文博客的技术支持太差了.正在头大的学习中...废话不多说,记录一下学习中的一些小细节.在遇到ge ...
- 讲一个linux服务启动报错问题排查
例子 首先我们在/usr/lib/systemd/system目录下创建一个服务文件,写下服务启动任务配置.下面我以prometheus的node_exporter为例 vim /usr/lib/sy ...
随机推荐
- 编写寄宿于windows服务的WCF服务
由于业务中有些任务需要在后台静默长期运行,或者有些服务队响应的要求比较苛刻,这样的WCF服务就不适合寄宿于IIS中.IIS每隔一段时间w3wp进程会闲置超时,造成服务的运行停止,因此这种耗时或者定时任 ...
- python里用变量命名改善代码质量
编程时,总会遇到各种各样的变量,取一个好的变量名能够有效提高代码的可读性,而且python是一种,动态类型的语言,良好的变量名,能够在编写代码或者再次阅读代码时提高效率. 1. 变量名不要太宽泛,要有 ...
- NumPy的使用(一)
# -*- coding: utf8 -*- from numpy import* a=arange(15).reshape(3,5) print a print a.shape print a.nd ...
- mssql sqlserver 视图如何加密,让第三方用户查看不到其中的SQL语句
转自:http://www.maomao365.com/?p=6719 摘要: 下文讲述视图加密的方法分享,通过此方法可以使视图只可使用,无法获取视图中sql脚本的内容,如下所示: 在创建视图的语法中 ...
- mssql sql server ceiling floor 函数用法简介
摘自: http://www.maomao365.com/?p=5581摘要: 下文主要讲述ceiling.floor函数的功能及举例说明 一.ceiling floor函数功能简介 ceiling ...
- NVIDIA显卡笔记本安装ubuntu驱动以及分辨率之详解
随着对ubuntu的了解,突然想在自己的笔记本上装一个双系统.在网上查了安装方法之后,发现因为nvidia显卡的原因会出现一些问题,结果在我自己装了之后发现问题要比看到的多,再看了无数个帖子之后,最终 ...
- python Django 文件下载示例
from django.http import StreamingHttpResponse#文件流 def big_file_download(request): # do something... ...
- SQLServer图数据库一些优点
上一篇简要介绍了图数据库的一些基本内容(初识SQL Server2017 图数据库(一)),本篇通过对比关系型一些语法来体现图数据库模式的一些优点,比如查询方便,语句易理解等. 在图数据库模型上构建查 ...
- rabbitMQ模式
1.hello 消息生产者p将消息放入队列 消费者监听队列,如果队列中有消息,就消费掉,消息被拿走后,自动从队列删除(隐患,消息可能没有被消费者正确处理,已经消失了,无法恢复) 应用场景:聊天室 案 ...
- C++实现第三方资源释放与载入过程(以DLL为例)
简介 我们经常看见有一些程序开始执行时会释放一些文件,以便于后续操作.例如一些病毒为了便于传播和隐藏,经常把一些需要用的动态库或是驱动文件打包进一个可执行文件中,再由需要使用的时候,再临时释放和加载. ...