zoukankan      html  css  js  c++  java
  • 通过实例来理解paxos算法

    背景

      Paxos算法是莱斯利·兰伯特(Leslie Lamport,就是 LaTeX 中的”La”,此人现在在微软研究院)于1990年提出的一种基于消息传递的一致性算法。由于算法难以理解起初并没有引起人们的重视,使Lamport在八年后重新发表到TOCS上[2]。即便如此paxos算法还是没有得到重视,2001年Lamport用可读性比较强的叙述性语言给出算法描述[3]。可见Lamport对paxos算法情有独钟。近几年paxos算法的普遍使用也证明它在分布式一致性算法中的重要地位。06年google的三篇论文初现“云”的端倪,其中的chubby锁服务使用paxos作为chubby cell中的一致性算法,paxos的人气从此一路狂飙。

    什么是paxos算法

      Paxos 算法是分布式一致性算法用来解决一个分布式系统如何就某个值(决议)达成一致的问题。一个典型的场景是,在一个分布式数据库系统中,如果各节点的初始状态一致,每个节点都执行相同的操作序列,那么他们最后能得到一个一致的状态1。为保证每个节点执行相同的命令序列,需要在每一条指令上执行一个”一致性算法”以保证每个节点看到的指令一致。

    paxos干啥的

      分布式系统中一般是通过多副本来保证可靠性,而多个副本之间会存在数据不一致的情况。所以必须有一个一致性算法来保证数据的一致,描述如下: 
      假如在分布式系统中初始是各个节点的数据是一致的,每个节点都顺序执行系列操作,然后每个节点最终的数据还是一致的。 
      Paxos算法就是解决这种分布式场景中的一致性问题。对于一般的开发人员来说,只需要知道paxos是一个分布式选举算法即可。多个节点之间存在两种通讯模型:共享内存(Shared memory)、消息传递(Messages passing),Paxos是基于消息传递的通讯模型的。

    paxos算法介绍

    Paxos保证以下三点: 
    1. 只有被提出提案才能被选定; 
    2. 只有一个值被选定; 
    3. 如果某个进程认为某个提案被选定了,那么这个提案必须是真的被选定的那个。 
    该一致性算法中有三个角色,分别是:proposer,acceptor,learner。它们之间通过消息来通讯。

    paxos算法的两阶段 
    prepare 阶段: 
      1. Proposer 选择一个提案编号 n,然后向acceptor的某个超过半数的子成员发送编号为n的 prepare 请求; 
      2. Acceptor 收到 prepare 消息后,如果提案的编号n大于该acceptor已经回复的所有 prepare 请求的编号,则 Acceptor 将自己上次已经批准的最大编号提案回复给 Proposer,并承诺不再回复小于 n 的提案;

    acceptor阶段: 
      1. 当一个 Proposer 收到了半数以上的 Acceptors 对 prepare 的回复后,就进入批准阶段。它要向回复 prepare 请求的 Acceptors 发送 accept 请求,包括编号 n 和根据 prepare阶段 决定的 value。这里的value是所有响应中编号最大的提案的value(如果根据 prepare 没有已经接受的 value,那么它可以自由决定 value)。 
      2. 在不违背自己向其他 Proposer 的承诺的前提下,Acceptor 收到 accept 请求后即接受这个请求。即如果acceptor收到这个针对n提案的accep请求,只要改acceptor尚未对编号大于n的prepare请求做出过响应,它就可以通过这个提案。

    流程图如下2: 

    具体实例 
    首先,给出proposer和acceptor的消息图3: 

    针对上面提出的两个阶段,分别解释: 
    prepare阶段 
    1. 
      每个server向proposer发送消息,表示自己要当leader,假设proposer收到消息的时间不一样,顺序是: proposer2 -> proposer1 -> proposer3,消息编号依次为1、2、3。 
      紧接着,proposer将消息发给acceptor中超过半数的子成员(这里选择两个),如图所示,proposer2向acceptor2和acceptor3发送编号为1的消息,proposer1向acceptor1和accepto2发送编号为2的消息,proposer3向acceptor2和acceptor3发送编号为3的消息。 
    2. 
      假设这时proposer1发送的消息先到达acceptor1和acceptor2,它们都没有接收过请求,所以接收该请求并返回【2,null】给proposer1,同时承诺不再接受编号小于2的请求; 
      紧接着,proposer2的消息到达acceptor2和acceptor3,acceptor3没有接受过请求,所以返回proposer2 【1,null】,并承诺不再接受编号小于1的消息。而acceptor2已经接受proposer1的请求并承诺不再接收编号小于2的请求,所以acceptor2拒绝proposer2的请求; 
      最后,proposer3的消息到达acceptor2和acceptor3,它们都接受过提议,但编号3的消息大于acceptor2已接受的2和acceptor3已接受的1,所以他们都接受该提议,并返回proposer3 【3,null】; 
      此时,proposer2没有收到过半的回复,所以重新取得编号4,并发送给acceptor2和acceptor3,此时编号4大于它们已接受的提案编号3,所以接受该提案,并返回proposer2 【4,null】。

    accept阶段 

      Proposer3收到半数以上(两个)的回复,并且返回的value为null,所以,proposer3提交了【3,server3】的提案。 
      Proposer1也收到过半回复,返回的value为null,所以proposer1提交了【2,server1】的提案。 
      Proposer2也收到过半回复,返回的value为null,所以proposer2提交了【4,server2】的提案。 

      Acceptor1和acceptor2接收到proposer1的提案【2,server1】,acceptor1通过该请求,acceptor2承诺不再接受编号小于4的提案,所以拒绝; 
      Acceptor2和acceptor3接收到proposer2的提案【4,server2】,都通过该提案; 
      Acceptor2和acceptor3接收到proposer3的提案【3,server3】,它们都承诺不再接受编号小于4的提案,所以都拒绝。 
      此时,过半的acceptor(acceptor2和acceptor3)都接受了提案【4,server2】,learner感知到提案的通过,learner开始学习提案,所以server2成为最终的leader。

    一些不错的参考资料 
    lamport的两篇论文: 
    Lamport, The part-time parliament, ACM Transactions on Computer Systems 16(2):133-169, 1998 
    Lamport, Paxos made simple, SIGACT News 32(4):18-25, 2001. 
    其他: 
    http://chuansong.me/n/1050231 
    http://www.cnblogs.com/ychellboy/archive/2009/12/29/1634801.html

    转载:Summer_ZJU

  • 相关阅读:
    html2pdf后逐页固定位置盖公章
    c#Stream学习笔记
    Flume -- 开源分布式日志收集系统
    Sqoop -- 用于Hadoop与关系数据库间数据导入导出工作的工具
    Hive -- 基于Hadoop的数据仓库分析工具
    HBase -- 基于HDFS的开源分布式NoSQL数据库
    ZooKeeper -- 分布式开源协调服务
    Hadoop学习(4)-- MapReduce
    Hadoop学习(3)-- 安装1.x版本
    Hadoop学习(2)-- HDFS
  • 原文地址:https://www.cnblogs.com/study-everyday/p/7279829.html
Copyright © 2011-2022 走看看