先讲一个故事。

从前,在国王Leslie Lamport的统治下,有个黑暗的希腊城邦叫paxos。城邦里有3类人,

  • 决策者
  • 提议者
  • 群众

虽然这是一个黑暗的城邦但是很民主,按照议会民主制的政治模式制订法律,群众有什么建议和意见都可以写提案交给提议者,提议者会把提案交给决策者来决策,决策者有奇数个,为什么要奇数个?很简单因为决策的方式很无脑,少数服从多数。最后决策者把刚出炉的决策昭告天下,群众得知决策结果。

等一下,那哪里黑暗呢?问题就出在“提议者会把提案交给决策者来决策”,那么多提案决策者先决策谁的?谁给的钱多就决策谁的。

那这样会有几个问题,决策者那么多,怎么保证最后决策的是同一个提案,以及怎么保证拿到所有提议者中最高的报价。

聪明又贪婪的决策者想到了一个办法:分两阶段报价

第一阶段

  1. 决策者接受所有比他当前持有报价高的报价,且不会通知之前报价的人
  2. 提议者给所有决策者报价,若有人比自己报价高就加价,有半数以上决策者接受自己报价就停止报价。

第一阶段结束的状态

每个提议者都觉得有半数以上的大佬接受了自己的提案,很开心。而决策者集团此刻的状态是一致的,半数以上同意的提案只有一个,这个就是报价最高的(因为高的总是可以覆盖低的),具体是谁提的who care,一致就行。

第二阶段

提议者去找收过自己钱的大佬签合同,这里有3种情况:

  1. 大佬都收了别人更高的价,回去拿钱继续贿赂,回到第一阶段重新升级;
  2. 大佬收到的最高报价是自己的,美滋滋,半数以上成功签合同,提案成功;
  3. 提议者回去拿钱回来继续贿赂的时候发现合同已经被签了且半数以上都签了这个提案,不干了,赶快把自己的提案换成已经签了的提案,再去提给所有大佬,看看能不能分一杯羹遇见还没签的大佬。

第二阶段结束的状态

所有提议者手头的提案都是一样的,因为有“赶快把自己的提案换成已经签了的提案”这一步;决策者集团所有成员最终接受的提案是一样的。

好的目的已经达到了,把这个提案昭告天下,让所有群众知道这件事。

故事说完了,用正确的姿势再简单介绍下paxos

分布式系统中的节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing)。

paxos作为基于消息传递通信模型的分布式系统,不可避免的会发生以下错误:进程可能会慢、被杀死或者重启,消息可能会延迟、丢失、重复,在基础 Paxos 场景中,先不考虑可能出现消息篡改即拜占庭错误的情况。

Paxos算法解决的问题是在一个可能发生上述异常的分布式系统中如何就某个值达成一致,保证不论发生以上任何异常,都不会破坏决议的一致性。一个典型的场景是,在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都执行相同的操作序列,那么他们最后能得到一个一致的状态。

为保证每个节点执行相同的命令序列,需要在每一条指令上执行一个“一致性算法”以保证每个节点看到的指令一致。一个通用的一致性算法可以应用在许多场景中,是分布式计算中的重要问题。

Paxos用于解决分布式系统中一致性问题,在一个Paxos过程只批准一个value,只有被prepare的value且被多数Acceptor接受才能被批准,被批准的value才能被learner。在paxos算法中,分为4种角色:

  • Acceptor:决策者
  • Proposer :提议者
  • Client:产生议题者(群众)
  • Learner:最终决策学习者(群众)

阶段一

  1. Proposer向半数以上的Acceptor发送Prepare请求并附上编号N。
  2. 若Acceptor收到一个编号为N的Prepare请求,且N大于该Acceptor已经响应过的所有Prepare请求的编号,那么它就会将它已经接受过的编号最大的提案(如果有的话)作为响应反馈给Proposer,同时该Acceptor承诺不再接受任何编号小于N的提案。
  3. Proposer若没有得到半数以上Acceptor的响应,则编号+1继续发起请求。

阶段二

  1. 如果Proposer收到半数以上Acceptor对其发出的编号为N的Prepare请求的响应,那么它就会发送一个[N,提案]Accept请求给半数以上的Acceptor。
  2. 如果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的故事...的更多相关文章

  1. 一步步做程序优化-讲一个用于OpenACC优化的程序(转载)

    一步步做程序优化[1]讲一个用于OpenACC优化的程序 分析下A,B,C为三个矩阵,A为m*n维,B为n*k维,C为m*k维,用A和B来计算C,计算方法是:C = alpha*A*B + beta* ...

  2. 来来来,有讲一个吐血的故事(matlab)之脚本运行路径是什么

    脚本运行路径是什么,这真是太重要!! 重要1:你默认保存的路径 重要2:你访问的相对路径 先放图: 再看一幅图: 我的操作,点击左侧的文件夹,使上框的显示栏路径不一样,再点击运行,发现pwd指示的路径 ...

  3. 讲一个关于RSA加密算法的故事

    有甲乙两个人,甲有两把钥匙,一把叫做甲的公钥,另一把叫做甲的私钥.乙同样有两把钥匙,一把叫做乙的公钥,另一把叫做乙的私钥. 某一天,甲乙成为了好朋友,甲想向乙发送一份保密数据,这份保密数据要求只有甲乙 ...

  4. 【C#进阶系列】01 CLR的执行模型——一个Hello World的故事

    好吧,废话少说,先上一章Hello World图: 我们有了一个Hello world程序,如此之简单,再加上我今天没有用汉字编程o(>﹏<)o,所以一切很简单明了. 故事开始: 编译: ...

  5. 一个update的小故事

    偶尔测试了一段小代码,写个循环 if object_id('tempdb..#TB') is not null drop table #TB go create table #TB ( ID int ...

  6. 第一讲 一个简单的Qt程序分析

    本文概要:通过一个简单的Qt程序来介绍Qt程序编写的基本框架与一些Qt程序中常见的概念 #include <QApplication> #include <QPushButton&g ...

  7. 讲一个使用jquery-slick旋转木马效果插件案例

    效果展示连接 http://www.jqcool.net/demo/201405/jquery-slick/ 今天刚接触这个插件,被这插件搞的大脑风暴了 所以来记录一下使用方法 首先注意一点 不特别标 ...

  8. python如何讲一个文件中的图片分到两个

    最近在做一个图像分类的比赛,作为初次接触深度学习的菜鸟,上手了keras.说实话,除了keras教程,中文博客的技术支持太差了.正在头大的学习中...废话不多说,记录一下学习中的一些小细节.在遇到ge ...

  9. 讲一个linux服务启动报错问题排查

    例子 首先我们在/usr/lib/systemd/system目录下创建一个服务文件,写下服务启动任务配置.下面我以prometheus的node_exporter为例 vim /usr/lib/sy ...

随机推荐

  1. leetcode-66.加一

    leetcode-66.加一 题意 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一. 最高位数字存放在数组的首位, 数组中每个元素只存储一个数字. 你可以假设除了整数 0 之外,这个 ...

  2. Linux16.04 LTS 环境下将cmake的项目转换成eclipse可导入可调试的工程项目

    Linux作为一个开源系统,其中的一个优势就是有效的将各种源码编译得到的库集合在一起,为项目的使用创建了便捷.通常情况下,我们在开发自己的开源项目时,喜欢使用cmake调用各种三方库,如opencv ...

  3. OSWatcher使用过程中小问题解决方法

    本文介绍一下在使用OSWatcher过程当中遇到的两个问题的解决方法.如有更好的方法,敬请留言. 1:OSWatcher在配置文件里面设置了参数OSW_COMPRESSION为gzip后,OSWatc ...

  4. [20190213]学习bbed-恢复删除的数据.txt

    [20190213]学习bbed-恢复删除的数据.txt --//以前也做过类似测试,当时在用bbed做verify时错误都不处理,当时的想法就是能读出就ok了.--//而且当时也做成功,纯粹是依葫芦 ...

  5. c指针类型的作用

    指针类型的作用 任何类型的指针占用的空间大小都是相同的(32位CPU是4字节:64位CPU是8字节) 既然任何类型的指针占用的空间大小都是相同的,为什么指针还需要类型呢?指针只是指向了一个内存地址,但 ...

  6. windows平台下实现高可用性和可扩展性-ARR和HLB

    本文档提供了关于如何将应用程序请求路由(ARR)与硬件负载均衡器一起使用以实现高可用性和可伸缩性的说明性指导.本文采用F5大IP负载均衡器来说明ARR与硬件负载平衡器之间的工作关系. IIS7.0及以 ...

  7. 关于激活Windows10专业版2018长期服务版

    之前重装了一次系统,偷懒用了小白一键重装,装好之后显示的是Windows10专业版2018长期服务版,当时也没想太多就放着用了. 然后 ,这几天一直提示  “你的windows许可证即将过期” ,就按 ...

  8. appium+robotframework常见技巧总结

    1.如何输入中文 方法: 在open application参数最后,新增unicodeKeyboard=True    resetKeyboard=True:不加入这两个参数时,中文无法输入 2.如 ...

  9. 7个小技巧,解决eclipse卡顿问题

    eclipse作为开发工具,每天都要使用,你肯定遇到过eclipse卡到想哭的时刻,严重影响开发效率啊!如果内存条不要钱,那就加内存吧!一个不够加两个!当然这都是玩笑话,如果不花钱也能解决问题,希望下 ...

  10. puppet使用 apache passsenger 作为前端 (centos)

    目录 1. 概要 2. nginx + passenger 配置 2.1. package 安装 2.2. 配置文件设置 2.3. rack 目录生成 概要 使用 nginx + passenger ...