Paxos算法是莱斯利·兰伯特Lamport 于1990年提出的一种基于消息传递的一致性算法。由于算法难以理解起初并没有引起人们的重视,使Lamport在八年后重新发表到TOCS上。即便如此paxos算法还是没有得到重视,2001年Lamport用可读性比较强的叙述性语言给出算法描述。可见Lamport对paxos算法情有独钟。

文章目录

  • 背景知识
  • 分布式系统:
  • 一致性
  • state machine replication
  • 强一致性算法
  • 主从同步
  • 多数派
  • Paxos算法
  • 什么是Paxos算法
  • 拜占庭问题
  • Paxos算法介绍
  • Paxos两阶段
  • 缺点


背景知识

在并发编程中,我们必须考虑的问题时如何在两个线程间进行通讯。这里的通讯指的是不同的线程之间如何交换信息。

目前有两种方式:

1、共享内存

2、消息传递(actor 模型)

分布式系统:

对于一个分布式系统,不能同时满足以下三点:

1、一致性(Consistence)

2、可用性(Availability)

3、分区容错性(Partition Tolerance)

一致性

一致性分为:弱一致性 和 强一致性

  • 弱一致性:指的是你当时写入一条数据,不能保证你写入后立刻就能够读到,但是过一会可以读到,保证了最终一致性

典型的实现是:DNS(Domain Name System)和 Gossip(Cassandra的通信协议)、

  • 强一致性:paxos 、raft 、ZAB

state machine replication

强一致性算法

主从同步

主从同步复制

1、Master接受写请求
2、Master复制日志至Slave
3、Master等待,直到所有从库返回(当所有的从服务器都返回给主master说,我们都把这条日志存储成功了,然后master会告诉client你这次操作成功了)

多数派

每次写都保证写入大于N/2个节点,每次读都保证从大于N/2个节点中读

在并发情况下,无法保证系统的正确性,顺序非常重要

Paxos算法

什么是Paxos算法

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

拜占庭问题

拜占庭将军问题(Byzantine failures),又称两军问题,1982年在莱斯利·兰波特研究分布式对等网络通信容错问题的论文中提出。在分布式系统的通讯过程中,可能会出现一些局部问题导致计算机发送错误信息,破坏系统一致性。因此,拜占庭将军问题本质上是关于点对点通信中的共识问题。

拜占庭将军问题起源于中世纪时期,由于拜占庭国土辽阔,军队之间通信只能依靠信差传递上层的作战信息。如果有叛徒故意错传上层领导作战信息,会导致作战方案不一致,从而出现“拜占庭将军问题”。互联网中的拜占庭将军问题是指在信道传输的过程中,部分节点可能会由于工作量过大或遭到某些恶意攻击而导致难以实现信息同步。

Paxos算法的前提假设是不存在拜占庭将军问题,即: 信道是安全的(信道可靠),发出的信号不会被篡改,因为Paxos算法是基于消息传递的。

从理论上来说,在分布式计算领域,试图在异步系统和不可靠信道上来达到一致性状态是不可能的。因此在对一致性的研究过程中,都往往假设信道是可靠的,而事实上,大多数系统都是部署在一个局域网中,因此消息被篡改的情况很罕见;另一方面,由于硬件和网络原因而造成的消息不完整问题,只需要一套简单的校验算法即可。因此,在实际工程中,可以假设所有的消息都是完整的,也就是没有被篡改。

Paxos算法介绍

在Paxos算法中,有三种角色:Client(请求的发起者)Proposer(提议者)、Acceptor(接受者)、Learners(学习者)

1、Client:系统外部角色,请求发起者。类似民众。

2、Proposer:接受Client请求,向集群提出提议Propose。并在冲突发生时,起到冲突调解的作用。类似议员向民众提出议案。

3、Acceptor:类似国会,接受提案

4、Learner:类似于记录员

在具体的实现中,一个进程可能 同时充当多种角色 。比如一个进程可能 既是Proposer又是Acceptor又是Learner 。Proposer负责提出提案,Acceptor负责对提案作出裁决(accept与否),learner负责学习提案结果。最终要达成一致的value就在提案里。只要Proposer发的提案被Acceptor接受(半数以上的Acceptor同意才行),Proposer就认为该提案里的value被选定了。Acceptor告诉Learner哪个value被选定,Learner就认为那个value被选定。只要Acceptor接受了某个提案,Acceptor就任务该提案里的value被选定了。

此外,Paxos算法必须保证以下三点:

  1. 只有被提出的value才能被选定;
  2. 只有一个value被选定;
  3. 如果某个进程认为某个value被选定了,那么这个value必须是真的被选定的那个。

注:这里某个数据的值并不只是狭义上的某个数,它可以是一条日志,也可以是一条命令(command)等根据应用场景不同,某个数据的值有不同的含义。

Paxos算法具有如下特性:

  1. 基于消息传递。允许消息传输的丢失、重复、乱序,但是不允许消息被篡改。
  2. 在节点数少于半数失效的情况下仍然能够正常工作,节点失效可以在任何时候发生而不影响算法正常执行。

Paxos两阶段

Paxos算法类似于两阶段提交2PC,其算法执行过程分为prepare和acceptor两个阶段。具体如下

不同的proposal必须具有不同的编号,这个的实现依硬件而异,

缺点

潜在问题:活锁(Liveness)或 dueling,实际在工业上很好解决。