zokeeper(2): paxos算法

Paxos算法是莱斯利·兰伯特(Leslie Lamport)1990年提出的一种基于消息传递的、具有高容错性的一致性算法。Google Chubby(分布式锁服务)的作者Mike Burrows说过,世上只有一种一致性算法,那就是Paxos,所有其他一致性算法都是Paxos算法的不完整版。Paxos算法是一种公认的晦涩难懂的算法,并且工程实现上也具有很大难度。较有名的Paxos工程实现有Google Chubby、ZAB、微信的PhxPaxos等。

Paxos算法是用于解决什么问题的呢?Paxos算法要解决的问题是,在分布式系统中如何就某个决议达成一致。

1) 三种角色

在Paxos算法中有三种角色,分别具有三种不同的行为。但很多时候,一个进程可能同时充当着多种角色。

 Proposer:提案(Proposal)的提议者。

 Acceptor:提案的表决者,即是否accept该提案。只有半数以上的Acceptor接受了某提案,那么该提案者被认定为“选定”。

 Learners:提案的学习者。当提案被选定后,其会同步并执行提案。

一个提案的表决者(Acceptor)会存在多个,但在一个集群中,提议者(Proposer)也是可能存在多个的,不同的提议者(Proposer)会提出不同的提案。而一致性算法则可以保证如下几

点:

 没有提案被提出则不会有提案被选定。

 每个提议者在提出提案时都会为该提案指定一个具有全局唯一性的、递增的提案编号N,即在整个集群中是唯一的。

 每个表决者在accept某提案后,会将该提案的编号N记录在本地,这样每个表决者中保存的已经被accept的提案中会存在一个编号最大的提案,其编号假设为maxN。每个表决者仅会accept编号大于自己本地maxN的提案。

 在众多提案中最终只能有一个提案被选定。

 一旦一个提案被选定,则其它服务器会主动同步(Learn)该提案到本地。

2) 算法过程描述

Paxos算法的执行过程划分为两个阶段:准备阶段prepare与接受阶段accept。

Aprepare阶段

1) 提议者(Proposer)准备提交一个编号为N的提议,于是其首先向所有表决者(Acceptor)发送prepare(N)请求,用于试探集群是否支持该编号的提议。

2) 每个表决者(Acceptor)中都保存着自己曾经accept过的提议中的最大编号maxN。当一个表决者接收到其它主机发送来的prepare(N)请求时,其会比较N与maxN的值。若N小于maxN,则说明该提议已过时,当前表决者采取不回应或回应Error的方式来拒绝该prepare(N)请求;若N大于等于maxN,则说明该提议是可以接受的,当前表决者会将其曾经已经accept的编号最大的提案Proposal(myid,maxN,value)反馈给提议者,以向提议者展示自己支持的提案意愿。其中第一个参数myid表示表决者Acceptor的标识id,第二个参数表示其曾接受的提案的最大编号maxN,第三个参数表示该提案的真正内容value。当然,若当前表决者还未曾accept过任何提议,则会将Proposal(myid,null,null)反馈给提议者。

Baccept阶段

1) 当提议者(Proposer)发出prepare(N)后,若收到了超过半数的表决者(Accepter)的反馈,那么该提议者就会将其真正的提案Proposal(N,value)发送给所有的表决者。

2) 当表决者(Acceptor)接收到提议者发送的Proposal(N,value)提案后,会再次拿出自己曾经accept过的提议中的最大编号maxN,及曾经反馈过的prepare的最大编号,让N与它们进行比较,若N大于等于这两个编号,则当前表决者accept该提案,并反馈给提议者。若N小于这两个编号,则表决者采取不回应或回应Error的方式来拒绝该提议。

3) 若提议者没有接收到超过半数的表决者的accept反馈,则重新进入prepare阶段,递增提案号,重新提出prepare请求。若提议者接收到的反馈数量超过了半数,则其它的未向提议者发送accept反馈的表决者将成为Learner,主动同步提议者的该提案。

原文地址:https://www.cnblogs.com/yintingting/p/6575222.html