参考:

https://www.cnblogs.com/linbingdong/p/6253479.html

https://zhuanlan.zhihu.com/p/31780743

https://zhuanlan.zhihu.com/p/58405630

《Paxos Made Simple》

https://www.microsoft.com/en-us/research/uploads/prod/2016/12/paxos-simple-Copy.pdf

https://www.zhihu.com/question/19787937

附件:

<<paxos-simple-Copy.pdf>>

前言

害,Paxos从大学的时候第一次看到接触,直到现在也没能弄清楚里面每一步的进化史和解决的痛点。

故,重新进行梳理,参考各类blog、wiki、论文写下这篇自己能够理解的文章。

这篇不仅包含了理论,还包含了很多推导过程,造成整个体积比较庞大。

Paxos是什么

Paxos算法是基于消息传递,且具有高度容错特性的一致性算法,是目前公认的解决分布式一致性问题的最有效算法之一。

除了基于消息传递,还有基于共享内存的。

这个算法收到了很多人的青睐,Google Chubby的作者 Mike Burrows认为只有一种一致性算法,就是Paxos,其他都是残次品。虽然有点夸张,但是说明了Paxos的地位。但Paxos好是好,算法却是晦涩难懂,不去钻研很难读透其每一步的执行过程和解决问题。

背景

Lamport宗师提出一种基于消息传递的分布式一致性算法,使其获得2013年的图灵奖。在1998年中的 《The Part-Time Parliament》论文中首次公开了Paxos,最初的描述使用了希腊小岛Paxos进行比喻,描述了小岛汇总通过决议的流程,并且以此为算法命名,在后续重新发表了更简单的版本《Paxos Made Simple》。(已经在上面参考,在线和离线都有)

强大

基本Paxos问世以来,就持续垄断了分布式一致性算法,Paxos就等同于分布式一致性,使用到的有Chubby、Megastore、Spanner、ZooKeeper、MySQL的主从复制等等都使用该算法进行分布式一致性问题的解决。

特点

生涩难解,更难实现。

Paxos利用了大多数(Majority)机制,保证了2N+1的容错能力,也就说允许集群中2N+1个节点中有N个节点同时出现故障。

问题产生背景

在常见的分布式系统中,总会发生很多机器宕机、网络波动、消息阻塞丢失等等。Paxos需要解决的就是在上述可能发生的所有情况内,怎么快速且正确的达成在集群内部对某个数据的值达成一致性,并且保证无论发生什么异常,都不会破坏整个系统的一致性。

也就是说Paxos算法允许运行在宕机故障的异步系统中,不要求消息的可靠传递,甚至消息丢失、延迟、乱序、重复等等情况都能够使用。

某个数据的值可以是一个值,可以是一个文件,一条message,一句命令等等。

基础概念

在Paxos算法中有三个角色:Proposer、Acceptor、Learners

一个提案 Proposal,最终达成一致性的值就在这个提案里面。

在具体的实现中,一个进程可能会扮演多个角色。(在多副本状态机中,每个副本同时具有Proposer、Acceptor、Learner三种角色)

        暂且认为提案就是value,即提案质保函value。在我们接下来的推导过程中会发现如果提案质包含value会出现一些问题。

        暂且认为 Proposer可以直接提出提案。在我们接下来的推导过程中,会发现如果Proposer直接提出提案会有问题,需要增加一个学习提案过程。

Proposer 提出propose; Acceptor可以接受accept提案;如果某个提案被选定chosen,那么这个提案中的value就被选定了。Learner只负责最终提案的学习。

所以 对某个数据的值达成一致 就是指的是Proposer、Acceptor、Learner都认为同一个value被选定chosen。那么他们选定某个value的条件如下:

Proposer:只要Proposer发的提案被Acceptor接受(刚开始先认为只需要一个Acceptor接受即可,在推导过程中发现需要半数以上的Acceptor统一才行),Proposer就认为该提案中的value被选定。

Acceptor:只要Acceptor接受了某个提案,Acceptor就任务该提案里的value被选定了。

Learner:Acceptor告诉Learner 哪个value被选定,那么Learner就认为哪个value被选定。不参与决策

问题描述

假设有一组可以 Propose value 的进程集合。一个一致性算法需要保证提出的这么多value中,只有一个value被选定。如果没有value被提出,那么value就不会被选定;如果有一个value被选定,那么所有进程都应该 learn到这个被选定的value。对于一致性算法,安全性 safety要求如下:

                只有被提出的value才能被选定。

                只有一个value被选定

如果某个进程认为某个value被选定了,那么这个value必须是真的被选定的。

我们不去精确定义其 活性liveness 的要求,我们的目标就是保证最终只有一个提出的value被选定。当一个value被选定后,进程最终也能学早这个value。 这个就是Paxos的目标。

假设不同角色之间可以通过发送消息来进行通讯,那么:

                A 每个角色以任意的速度执行,可能因出错而停止、重启、断开服务等。一个value被选定后,所有的角色可能失败然后重启,除非那些失败重启的角色能记录某些信息,否则等他们重启后无法确定被选定的值。

                B 消息在传递过程中可能出现任意时长的延迟、重复、缺失。但保证消息不被破坏、篡改等问题(拜占庭将军问题)。

推导过程

假设:Acceptor只有一个

假设只有一个Acceptor 多个Proposer,只要Acceptor接受到它的第一提案,则该提案被选定,该提案中的value就是被选定的value,这样只有这个value被选定。

但是如果这个Acceptor出现宕机,那么整个系统就无法发进行工作。

所以为了满足条件A,必须存在多个Acceptor

假设:Acceprot有多个

多个Acceptor接受value值,假设只有一个Proposer提出了value,那么这个value会被所有Acceptor接受。

那么得到第一个约束:

                P1:一个Acceptor必须接受它收到的第一个提案。

这个时候,如果有多个Proposer分别提出不同的value,给了不同的Acceptor。根据P1规则,Acceptor分贝接受自己收到的value,那么就会导致不同的value在各个Acceptor手中。

那么上述时候到底以哪一个Acceptor的值作为最后的输出方案呢?这个时候就需要引入一个规定:

                规定:一个提案被选定,必须要被超过半数以上的Acceptor所接受

这样就避免了一个集群出现多个value值的情况,如果有多个值,则认为value并没有被最终选定。那么当出现多个value的时候,怎么进行推导向最终值的目的呢?

                【一个Acceptor必须能够接受不止一个提案】

如果一个Acceptor能够接受多个提案,那么他就不能仅仅保存value的形式,我还需要一个编号,来表达这个提案的版本号,也就是说 提案的形式必须发生更改:

                提案=value+版本号

版本号怎么进行选择?后续的提案编号都是用M进行代替,value使用V进行代替。M必须是递增的!

                版本号可以考虑为 时间戳+ip(本机/线程标示符)

选定后的更新

再次回顾一下,如上图,3个propose被三个acceptor接受,如果每个acceptor不能接受多个提案,那么就无法进行最终value一致性的选择。如果 提案仅仅保存value,那么就无法管控提案的版本号,可能造成循环(如a到b,b到c,c到a不停覆盖提案)。总结上述后继续推导。

当前虽然允许多个提案被选定,但必须保证所有被选定的提案都具有相同的value值,那么如何在Acceptor接收多个值的时候进行选择保留一个value呢?新增约束:

                P2:如果某个value为v的提案被选定了,那么只有更高编号M的value才能够被选定

一个提案被Acceptor接收才可能被选定,因此可以写成:

                P2A:如果某个value为v的提案被Acceptor选定,那么只有更高编号M的value才能够被Acceptor接受

考虑下一下情况:

假设总共有5个Acceptor/Proposer。 Proposer2提出[M1,V1]的提案,Acceptor有半数以上接受了这个提案(假定2435),于是对于Acceptor2435来说,[M1,V1]就是最终的选定。Acceptor1刚刚从宕机中恢复过来,此前并没有接受到任何提案,Proposer1向Acceptor1发送了[M2,V2]的提案(V2!=V1&&M2>M1),对于Acceptor1来讲,这个就是接受到的第一个提案,根据P1,必须接受这个提案。

那么就会存在Acceptor1接受V2,而Acceptor2345接受V1,出现了不一致;并且P2A也不能约束到这种情况。

因此我们需要对P2A进行约束泛化,将强化转移到Proposer身上:

                P2B:如果某个为value的提案被选定了,那么之后任何Proposer提出的编号更高的提案的value也必须是value。

那么,如何确保在某个value提案被选定后,Proposer提出的编号更高的提案都是value呢:

                P2C:对于任意的M和V,如果提案【M,V】被提出,那么存在一个半数以上的Acceptor组成的集合S,满足一下两个条件中的任意一个:

                S中每个Acceptor都没有接受过编号小于M的提案。(这个M是最小的提案,根本不能够影响集合S)

                S中Acceptor接受过的最大编号提案的value。(这个M是是S集合中版本最高的,且V都是value)

Proposer生成提案

刚刚讲了四个P2都是为了如果已经选定value,那么进行更新的时候必须的约束条件(约束Acceptor、Proposer)。

对于P2B来说,Proposer为了满足这个条件,就必须去查询已经被选定或者可能被选定的value,然后以这个value作为自己的提案来进行提出。如果value并没有被选定,那么Proposer才可以指定只记得value,这样才能慢慢归一化。

这个查询学习过程,是通过Prepare请求实现。

可以提炼出提案的生成算法:

  1. Proposer选择一个新的提案编号M,然后向某个Acceptor集合S(半数以上)发送请求,请求集合S中每个Acceptor对这个【M,V】做出如下的响应reponse:

    1. 向Proposer承诺,不接受任何小于M编号的提案。
    2. 如果Acceptor接受过提案,那么就向Proposer响应已经接受过的编号小于M的最大编号提案和Value。

我们将这个称之为 编号为M的Prepare请求。

  1. 如果Proposer收到了半数以上的Acceptor的响应,那么他就可以生成编号为【M,V】天,这里的V是所有响应中编号最大的提案的value。如果半数集合S并没有进行value值的响应,那么Proposer就可以自己进行选择。

生成提案后,Proposer会将提案发送给半数以上的Acceptor(可以并不是集合S),并期望这次集合中的Acceptor能够接受这个提案。

我们将这个称之为Accept请求。

Acceptor接受提案

由于以前说过的网络故障、丢包、错误等等,Acceptor可以忽略任何请求(上面提到的prepare请求&Accept请求),并且不用担心任何的安全性影响。那么我们就仅仅讨论什么时候Acceptor进行响应就行。

我们对Acceptor接受提案给出以下约束:

                P1A:一个Acceptor只要尚未响应过任何编号大于M的Prepare请求,那么他就可以接受这个编号为N的提案。

如果Acceptor收到一个编号为M的Prepare请求,在这个之前已经响应过编号大于M的其他Prepare请求。则根据P1A,Acceptor就不能接受M的提案。因此Acceptor可以直接忽视,或者返回一个ERROR(返回已经接受过的编号小于M的提案与Value)。

所以在Acceptor的世界里,只需要记住:

  1. 已经接受的编号最大的提案。
  2. 已经响应的最大请求编号。

我接受过比你编号M更小的编号的提案,但我能够响应你,并且答应你忽视小于等于M的Prepare请求和小于M的Propose请求(这里后者没有等于,因为我要接收你的Propose请求),并且告诉你我已经接收到过的更小编号的提案的【M,V】。

Paxos算法描述

上述都是对约束进行的推导,现在总结下Paxos的算法流程。Paxos分为两个阶段:

阶段一:

Proposer选择一个提案编号M,然后向半数以上的Acceptor发送编号为M的Prepare请求。

如果Acceptor收到了一个编号为M到的Prepare请求,且M大于Acceptor已经响应过的所有的Prepare请求编号,那么它就会将他自己已经接受过的最大提案进行返回(如果没有就返回空),并承诺不再接受任何小于M的提案。

阶段二:

如果Proposer收到半数以上的Acceptor对其发送的编号为M的Prepare请求的响应,那么他就会发送一个针对【M,V】提案的Accept请求给半数以上的Acceptor(并不一定是刚刚的集合)。注意:V为阶段一Acceptor响应编号中最大的提案的value,如果都返回的为null,则V由Proposer自己决定。

如果Acceptor收到了一个针对编号为M提案的Accept请求,只要该Acceptor没有对编号大于M的Prepare请求作出过响应,他就接受这个提案。(V呢?)

Learner学习被选定的value

Learner学习被选定的value有如下三种方案:

第一种为广播式:

                发送给所有Learner进行学习。那么会造成Acceptor*Learner次网络信息量,信息量过大。

第二种为Leader式:

                发送给主Learner,主Learner发送给其他。这样就会形成单节点故障(解决参考Multi-Paxos)

第三种为ISR式:

                小集合学习后通知大集群。

如何保证Paxos算法的活性

假设有两个Proposer依次提出编号递增的提案,最终会陷入死循环,没有value被选定。

Proposer1 发出 M1 prepare请求,收到过半的响应,完成阶段一。

同时Proposer2发出编号为M2的请求,也收到过半响应,完成阶段一。

Proposer1发出Accept请求,没有半数接受,重新发起M3 prepare请求。

Proposer2发出Accept请求,没有半数接受,重新发起M4 prepare请求。

……

两个Proposers交替的Prepare请求成功,导致Acceptor无法接受,造成Accept失败,形成活锁(Livelock

通过选取主Proposer,就可以保证Paxos算法的活性。

至此,我们能够得到一个既能保证安全,又能保证活性的分布式一致性算法。

伪代码实现

Multi-Paxos

在 Basic Paxos 中,只能对一个值进行决议,决议的形成至少需要两次网络的来回。在高并发的场景下会需要更多的网络来回,甚至在上面的Proposer交替Prepare成功还会造成活锁的形成。

那么在实际躬工程中,需要确定多个值,需要更高的效率进行,所以产生了Multi-Paxos算法,对Paxos算法进行了两点改进:

Instance ID 标识

针对每一个要确定的值,运行一次Paxos算法实例(Instance),形成决议。每一个Paxos实例使用唯一的Instance ID标识。

Leader

在所有Proposers中选举一个Leader,由Leader唯一地提交Proposal给Acceptors进行表决,这样没有Proposer竞争,快速高效解决活锁问题。甚至由于只有一个Leader Proposer,那么prepare阶段都可以跳过,直接进行提交。

过程

也就是说Multi-Paxos首先需要进行Leader的选举,Leader的选举也可以认为是一次决议的Value的形成,直接使用Basic-Paxos进行选举。如果宕机重新进行Basic-Paxos的选举。

容错

多个Leader会有问题么?多个Leader其实如果还是二阶段提交提案,那么就退化成为Basci Paxos而已,不影响其安全性。

总结

Paxos分为三个阶段:

Prepare阶段:

                Proposer们向Acceptor发送Prepare请求,Acceptors针对收到的Prepare请求进行Promise承诺。

Accept阶段:

                Proposer们根据接收到的Promise承诺后,考虑是否进行Propose请求,Acceptor针对收到的Propose请求进行Accept处理并返回结果。Proposer接收到结果后知道自己是否成功。

Learn阶段:

                决议成功后,Acceptor会将最终提案Value发送给所有Learner

在Proposer中:

                想要发出提案必须先进行一次学习,发送Prepare请求,试探后根据返回V进行Propose请求。

在Acceptor中:

                接受一个提案需要承诺别人一些东西,Prepare请求则不再接受小于等于这个prepare的请求,并且不接受小于Propose请求。

提问

Paxos算法中,有几个角色,分别是什么作用。

Paxos算法中,有几个阶段,每个阶段的作用。

Paxos的缺陷是什么,怎么进行弥补。

你能写一个Paxos的伪代码么?

后记

终于写完,也重新梳理完所有,其实在各个博客中也能搜索到很多相关文章,但读起来还是不太行,自己写个,也不太行,后续可以写个精简版,进行整理。

Raft也是分布式协议,keep studying。

Paxos算法原理与推导相关推荐

  1. 分布式系列文章——Paxos算法原理与推导

    Paxos算法在分布式领域具有非常重要的地位.但是Paxos算法有两个比较明显的缺点:1.难以理解 2.工程实现更难. 网上有很多讲解Paxos算法的文章,但是质量参差不齐.看了很多关于Paxos的资 ...

  2. 【机器学习】算法原理详细推导与实现(七):决策树算法

    [机器学习]算法原理详细推导与实现(七):决策树算法 在之前的文章中,对于介绍的分类算法有逻辑回归算法和朴素贝叶斯算法,这类算法都是二分类的分类器,但是往往只实际问题中yyy不仅仅只有{0,1}\{0 ...

  3. 常用机器学习算法原理及推导

    周末花半天多的时间整理了一下常用机器学习算法的原理及推导,分享出来给大家. 线性回归和逻辑回归 支持向量机(这个貌似工作中不怎么用,就用了之前的笔记) 决策树和随机森林 GBDT Xgboost和Li ...

  4. Paxos算法原理和过程解析

    我们了解了2PC和3PC之后,我们可以发现,无论是二阶段提交还是三阶段提交都无法彻底解决分布式的一致性问题以及无法解决太过保守及容错性不好.Google Chubby的作者Mike Burrows说过 ...

  5. BP神经网络(反向传播算法原理、推导过程、计算步骤)

    BP神经网络 1.反向传播算法的原理 2.反向传播算法参数学习的推导 3.反向传播算法参数更新案例 3.1 反向传播的具体计算步骤 3.1.1 计算输出层的误差 3.1.2 计算隐藏层误差 3.1.3 ...

  6. 干货 | 三维点云配准:ICP 算法原理及推导

    编者荐语 点云配准可以分为粗配准(Coarse Registration)和精配准(Fine Registration)两步.粗配准指的是在两幅点云之间的变换完全未知的情况下进行较为粗糙的配准,目的主 ...

  7. KF算法学习(一):算法原理与推导

    学习过程中接触到了卡尔曼滤波,因为自己的数学渣属性,特地把自己的推导过程记录下来以加深理解,虽然有重复造轮子的嫌疑.. 推导公式过多,图方便自己用的office写的文档,后来发现打算上传到博客上时很无 ...

  8. 六轴机械臂运动学算法原理及其推导过程

    网站上关于六轴机械臂piper算法的讲解有很多,但其腕点姿态的推到较为模糊,故此写一篇关于六轴机械臂piper算法的推导讲解,供有缘人参考,如果您觉得有用,可以点个赞,吾将不胜感激,若是推导过程存在错 ...

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

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

  10. adaboost 算法 原理

    Adaboost 算法 算法简介 (1)adaboost是有监督的分类算法 有监督 无监督的区别,直观来看,区别在于训练集中,是否需要包括因变量Y. 例如: 无监督算法 -- K-means聚类算法, ...

最新文章

  1. Nginx相关基础配置详解
  2. 浅析域名购买的注意事项
  3. 归并排序模板(附求逆序对)
  4. 退出命令_Vim命令报错问题:无法用:wq命令保存并退出只读文件
  5. 智能小程序档案馆——如何给“包”瘦身
  6. mysql使用navicat(建表前与建表后)添加时间戳(创建时间、自动更新时间)
  7. FPGA时序约束、时序分析(一)
  8. Algorithm:贪心策略之区间覆盖问题
  9. MDaemon替换注册码怎样人工激活.docx
  10. 单片机:楼梯照明灯控制
  11. 基于MATLAB绘制双纵坐标轴图
  12. 打印机驱动无法安装到计算机是,电脑打印机无法安装驱动的解决方法
  13. 华东师大计算机全国排名,华东师范大学就这水平进的985?
  14. 修复YYC松鼠短视频系统搜索功能无法使用问题
  15. 京东店铺所有商品API接口(整店商品查询API接口),京东店铺商品API接口
  16. SVN命令使用提示版本过旧的问题E155019
  17. 中路由怎么配置_【国土语录 第64期】茶队点金大鱼后发生了什么;否定Fy关于茶队中路看法...
  18. 2019 - 02 typescript的学习(结合cocos creator)
  19. 周易六十四卦——讼卦
  20. 阿朱,是时候拥抱 Linux 了!

热门文章

  1. 联想服务器引导盘制作工具,联想(Lenovo)服务器System X 系列无法进入引导盘Server Guide的解决方案 - 王耍耍...
  2. wajueji.php,独家解析:为什么说斗山DX55-9C是5吨小挖掘机中的新机皇
  3. jQuery 进度条实现
  4. 中国英语学习论坛(2:考 研 英 语 资 料 索 引)
  5. 顺丰快递:请签收MySQL灵魂十连问
  6. 极通ewebs3.2企业版介绍
  7. 【小教程】完全卸载Adobe Creative Cloud以及删除资源管理器左侧Creative Cloud Files导航栏的最快方法
  8. python 东方财富接口_东方财富 股票数据接口_
  9. 全网营销干货:物联网时代,为什么要关注线下大数据?
  10. 第二章 python自定义函数与类(一)