维基的简介:Paxos算法是莱斯利·兰伯特(Leslie Lamport,就是 LaTeX 中的"La",此人现在在微软研究院)于1990年提出的一种基于消息传递且具有高度容错特性的一致性算法。

Paxos算法目前在Google的Chubby、MegaStore、Spanner等系统中得到了应用,Hadoop中的ZooKeeper也使用了Paxos算法,在上面的各个系统中,使用的算法与Lamport提出的原始Paxos并不完全一样,这个以后再慢慢分析。本博文的目的是,如何让一个小白在半个小时之内理解Paxos算法的思想。小白可能对数学不感兴趣,对分布式的复杂理论不熟悉,只是一个入门级程序员。之所以想写这篇博文,是因为自己看了网上很多介绍Paxos算法的文章,以及博客,包括Lamport的论文,感觉还是难以理解,大多过于复杂,本人一直认为,复杂高深的理论背后一定基于一些通用的规律,而这些通用的规律在生活中其实我们早就遇到过,甚至用过。所以,我们先忽略Paxos算法本身,从生活中的小事开始谈起。

假如有一群驴友要决定中秋节去旅游,这群驴友分布在全国各地,假定一共25个人,分别在不同的省,要决定到底去拉萨、昆明、三亚等等哪个地点(会合时间中秋节已经定了,此时需要决定旅游地)。最直接的方式当然就是建一个QQ群,大家都在里面投票,按照少数服从多数的原则。这种方式类似于“共享内存”实现的一致性,实现起来简单,但Paxos算法不是这种场景,因为Paxos算法认为这种方式有一个很大的问题,就是QQ服务器挂掉怎么办?Paxos的原则是容错性一定要很强。所以,Paxos的场景类似于这25个人相互之间只能发短信,为了这件事情能够达成一致,这25个人找了另外的5个人(当然这5个人可以从25个人中选,这里为了描述方便,就单拿出另外5个人),比如北京、上海、广州、深圳、成都的5个人,25个人都给他们发短信,告诉自己倾向的旅游地。这5个人相互之间可以并不通信,只接受25个人发过来的短信。这25个人我们称为驴友,那5个人称为队长。

先来看驴友的逻辑。驴友可以给任意5个队长都发短信,发短信的过程分为两个步骤:

第一步(申请阶段):询问5个队长,试图与队长沟通旅游地。因为每个队长一直会收到不同驴友的短信,不能跟多个驴友一起沟通,在任何时刻只能跟一个驴友沟通,按照什么原则才能做到公平公正公开呢?这些短信都带有发送时间,队长采用的原则是同意与短信发送时间最新的驴友沟通,如果出现了更新的短信,则与短信更新的驴友沟通。总之,作为一个有话语权的人,只有时刻保持倾听最新的呼声,才能做出最明智的选择。在驴友发出短信后,等着队长回复。某些队长可能会回复说,你这条短信太老了,我不与你沟通;有些队长则可能返回说,你的短信是我收到的最新的,我同意跟你沟通。对于后面这些队长,还得返回自己决定的旅游地。关于队长是怎么决定旅游地的,后面再说。

对于驴友来说,第一步必须至少有半数以上队长都同意沟通了,才能进入下一步。否则,你连沟通的资格都没有,一直在那儿狂发吧。你发的短信更新,你获得沟通权的可能性才更大。。。。。。

因为至少有半数以上队长(也就是3个队长以上)同意,你才能与队长们进行实质性的沟通,也就是进入第二步;而队长在任何时候只能跟1个驴友沟通,所以,在任何时候,不可能出现两个驴友都达到了这个状态。。。当然,你可以通过狂发短信把沟通权抢了。。。。

对于获得沟通权的那个驴友(称为A),那些队长会给他发送他们自己决定的旅游地(也可能都还没有决定)。可以看出,各个队长是自己决定旅游地的,队长之间无需沟通。

第二步(沟通阶段):这个幸运的驴友收到了队长们给他发的旅游地,可能有几种情况:

第一种情况:跟A沟通的队长们(不一定是全部5个队长,但是半数以上)全部都还没有决定到底去那儿旅游,此时驴友A心花怒放,给这些队长发第二条短信,告诉他们自己希望的旅游地(比如马尔代夫);

可能会收到两种结果:一是半数以上队长都同意了,于是表明A建议的马尔代夫被半数以上队长都同意了,整个决定过程完毕了,其它驴友迟早会知道这个消息的,A先去收拾东西准备去马尔代夫;除此之外,表明失败。可能队长出故障了,比如某个队长在跟女朋友打电话等等,也可能被其它驴友抢占沟通权了(因为队长喜新厌旧嘛,只有要更新的驴友给自己发短信,自己就与新人沟通,A的建议队长不同意)等等。不管怎么说,苦逼的A还得重新从第一步开始,重新给队长们发短信申请。

第二种情况:至少有一个队长已经决定旅游地了,A可能会收到来自不同队长决定的多个旅游地,这些旅游地是不同队长跟不同驴友在不同时间上做出的决定,那么,A会先看一下,是不是有的旅游地已经被半数以上队长同意了(比如3个队长都同意去三亚,1个同意去昆明,另外一个没搭理A),如果出现了这种情况,那就别扯了,说明整个决定过程已经达成一致了,收拾收拾准备去三亚吧,结束了;如果都没有达到半数以上(比如1个同意去昆明,1个同意去三亚,2个同意去拉萨,1个没搭理我),A作为一个高素质驴友,也不按照自己的意愿乱来了(Paxos的关键所在,后者认同前者,否则整个决定过程永无止境),虽然自己原来可能想去马尔代夫等等。就给队长们发第二条短信的时候,告诉他们自己希望的旅游地,就是自己收到的那堆旅游地中最新决定的那个。(比如,去昆明那个是北京那个队长前1分钟决定的,去三亚的决定是上海那个队长1个小时之前做出来的,于是顶昆明)。驴友A的想法是,既然有队长已经做决定了,那我就干脆顶最新那个决定。

从上面的逻辑可以看出,一旦某个时刻有半数以上队长同意了某个地点比如昆明,紧跟着后面的驴友B继续发短信时,如果获得沟通权,因为半数以上队长都同意与B沟通了,B必然会收到至少一个队长给他发的昆明这个结果,B于是会顶这个最新地点,不会更改,因为后面的驴友都会顶昆明,因此同意昆明的队长越来越多,最终必然达成一致。

看完了驴友的逻辑,那么队长的逻辑是什么呢?

队长的逻辑比较简单。

在申请阶段,队长只会选择与最新发申请短信的驴友沟通,队长知道自己接收到最新短信的时间,对于更老的短信,队长不会搭理;队长同意沟通了的话,会把自己决定的旅游地(或者还没决定这一信息)发给驴友。

在沟通阶段,驴友C会把自己希望的旅游地发过来(同时会附加上自己申请短信的时间,比如3分钟前),所以队长要检查一下,如果这个时间(3分钟前)确实是当前自己最新接收到申请短信的时间(说明这段时间没有驴友要跟自己沟通),那么,队长就同意驴友C的这个旅游地了(比如昆明,哪怕自己1个小时前已经做过去三亚的决定,谁让C更新呢,于是更新为昆明);如果不是最新的,说明这3分钟内又有其它驴友D跟自己申请了,因为自己是个喜新厌旧的家伙,同意与D沟通了,所以驴友C的决定自己不会同意,等着D一会儿要发过来的决定吧。

Paxos的基本思想大致就是上面的过程。让我们来对应一下。

Paxos主要用于保证分布式存储中副本(或者状态)的一致性。副本要保持一致,那么,所有副本的更新序列就要保持一致。因为数据的增删改查操作一般都存在多个客户端并发操作,到底哪个客户端先做,哪个客户端后做,这就是更新顺序。如果不是分布式,那么可以利用加锁的方法,谁先申请到锁,谁就先操作。但是在分布式条件下,存在多个副本,如果依赖申请锁+副本同步更新完毕再释放锁,那么需要有分配锁的这么一个节点(如果是多个锁分配节点,那么又出现分布式锁管理的需求,把锁给哪一个客户端又成为一个难点),这个节点又成为单点,岂不是可靠性不行了,失去了分布式多副本的意义,同时性能也很差,另外,还会出现死锁等情况。

所以,说来说去,只有解决分布式条件下的一致性问题,似乎才能解决本质问题。

如上面的例子,Paxos解决这一问题利用的是选举,少数服从多数的思想,只要2N+1个节点中,有N个以上同意了某个决定,则认为系统达到了一致,并且按照Paxos原则,最终理论上也达到了一致,不会再改变。这样的话,客户端不必与所有服务器通信,选择与大部分通信即可;也无需服务器都全部处于工作状态,有一些服务器挂掉,只有保证半数以上存活着,整个过程也能持续下去,容错性相当好。

Paxos中的Acceptor就相当于上面的队长,Proposer就相当于上面的驴友,epoch编号就相当于例子中申请短信的发送时间。关于Paxos的正式描述已经很多了,这里就不复述了,关于Paxos正确性的证明,因为比较复杂,以后有时间再分析。另外,Paxos最消耗时间的地方就在于需要半数以上同意沟通了才能进入第二步,试想一下,一开始,所有驴友就给队长狂发短信,每个队长收到的最新短信的是不同驴友,这样,就难以达到半数以上都同意与某个驴友沟通的状态,为了减小这个时间,Paxos还有Fast Paxos的改进等等,有空再分析。

倒是有一些问题可以思考一下:在Paxos之前,或者说除了Chubby,ZooKeeper这些系统,其它分布式系统同样面临这样的一致性问题,比如HDFS、分布式数据库、Amazon的Dynamo等等,解决思路又不同,有空再进行对比分析。

其它资料:

https://yq.aliyun.com/articles/54371?spm=5176.8067842.tagmain.63.oSTajh

https://yq.aliyun.com/articles/54479?spm=5176.8067842.tagmain.69.oSTajh

通俗理解Paxos算法相关推荐

  1. 一步一步理解Paxos算法

    一步一步理解Paxos算法 作者:jw (360电商技术组) 背景 Paxos算法是Lamport于1990年提出的一种基于消息传递的一致性算法.由于算法难以理解起初并没有引起人们的重视,使Lampo ...

  2. 如何透彻理解 Paxos 算法?

    我们主要讲解"如何透彻理解 Paxos 算法"? 文章目录 Quorum 机制 Quorum 定义 Quorum 的应用 Paxos 节点的角色和交互 Paxos 的节点角色 Pr ...

  3. 03 如何透彻理解 Paxos 算法?

    文章目录 03 如何透彻理解 Paxos 算法? Quorum 机制 Quorum 定义 Quorum 的应用 Paxos 节点的角色和交互 Paxos 的节点角色 Proposer 提案者 Acce ...

  4. 深入浅出理解Paxos算法

    Paxos算法是莱斯利·兰伯特(英语:Leslie Lamport,LaTeX中的「La」)于1990年提出的一种基于消息传递且具有高度容错特性的一致性算法. Paxos算法一开始非常难以理解,但是一 ...

  5. 理解paxos算法--事前咨询,事中决定,事后提交

    要点: (1)Paxos算法描述的过程发生在"一次选举"的过程中,一次选举包括多轮的提案(proposal)提交,批准,决议的过程 (2)一个proposal(提案)包含该提案的唯 ...

  6. 【图解】算法原理!通俗理解机器学习算法

    机器之心报道 机器之心编辑部 算法公式挺费神,机器学习太伤人.任何一个刚入门机器学习的人都会被复杂的公式和晦涩难懂的术语吓到.但其实,如果有通俗易懂的图解,理解机器学习的原理就会非常容易.本文整理了一 ...

  7. Algorithms, 4th Edition 算法4精华笔记,通俗理解,算法收集与强化

    JVM 是 java 程序员永远的考题,算法是所有程序员永久的考题.这应该是很多人的共识,不管是谁,学习的路上我们时常遇到迷茫阶段,抓住最根本的东西你永远不会觉得迷失. 年假之前,我就规定自己要完成多 ...

  8. 【大道至简】机器学习算法之EM算法(Expectation Maximization Algorithm)详解(附代码)---通俗理解EM算法。

    ☕️ 本文来自专栏:大道至简之机器学习系列专栏

  9. 区块链共识之Paxos算法理解与实战

    0.前言 本文记录笔者学习和理解区块链共识算法Paxos的点滴,文章比较长,需要耐心来细细琢磨,笔者也是苦战了一个周末才对此有那么一点初步了解,有问题的地方请不吝斧正! 1.初始是阅读本文后续内容的基 ...

最新文章

  1. 八成名校AI教授,都拿过谷歌微软亚马逊们的钱
  2. IBM一分为二,将剥离IT基础设施部门,未来专注云计算和AI
  3. django_2.0_请求处理
  4. 认识AndEngine选自Android 2D游戏引擎AndEngine快速入门教程
  5. 体系文件管理解决方案
  6. ReactiveStream01
  7. 2021HDU多校6 - 7028 Decomposition(构造)
  8. Java 基于 UDP 实现 Socket中的多客户端通信
  9. IOS设置导航栏的背景图片和文字
  10. python BeautifulSoup 爬虫运行出现 exited with code -1073741571
  11. Linux系统编程18:超详解进程程序替换exec函数的一些用法
  12. NLTK自然语言处理简介
  13. 28 岁字节程序员退休,财务自由
  14. LINUX下载编译libvpx
  15. Github每日精选(第16期):录屏工具ScreenToGif
  16. 回归分析的几个问题:异方差性、自相关性、多重共线性
  17. 记录使用浏览器扫码功能(pad 笔记本 手机)
  18. Greenplum 数据库和schema管理
  19. 360能删除mysql吗_如何把Mysql卸载干净(亲测有效)
  20. 仿牛客网论坛项目资料整理

热门文章

  1. 使用SCVMM2012从hyper-v 2.0平台往hyper-v 3.0平台迁移VM虚拟机的报错(2)
  2. WinForm程序设计-根据工具栏上按钮的标题调用不同的功能表单
  3. 牛客 - Elo mountains(AC自动机+可持久化数组优化)
  4. HDU - 4685 Prince and Princess(强连通缩点+二分图完备匹配)
  5. python 输入10个整数_2019-07-18 python练习:编写一个程序,要求用户输入10个整数,然后输出其中最大的奇数,如果用户没有输入奇数,则输出一个消息进行说明。...
  6. java 异或_脚本语言系列之Java | Java中的运算符
  7. php 下载的压缩文件,php在线压缩打包rar并自动下载文件的例子
  8. GROUP BY 子句中 选择列表中的列无效,因为该列没有包含在聚合函数或
  9. EventBus设计与实现分析——事件的发布
  10. python中list和str互相转换