分布式共识算法学习

同步复制的几种方式

  • 单主复制:主节点接收客户端的请求,从节点只能处理读请求,从主节点同步最新的数据。适合于读多写少的场景。

    • 优点:简单易懂,相对容易实现。仅主节点执行并发写,能够保证操作的顺序。

    • 缺点:写入瓶颈取决于单节点的写入能力,主节点宕机后可能停机或错误。

      • 宕机后手动切换:相对安全,但是人工介入可能造成较长时间停机

      • 宕机后自动切换:从节点监听主节点状态并选主,可能出现“脑裂”

  • 多主复制:为了应对单主复制的缺陷(写入瓶颈、单主挂掉后的错误),但是多主带来了数据冲突的问题。解决的复杂度大于其带来的优势,因此很少有系统使用多主复制。

  • 无主复制:摒弃了数据写入到主节点然后同步数据到从节点的做法,客户端不只是向一个节点发送写请求,而是将请求发送给多个节点(甚至是全部的节点),收到W个节点的确认消息就代表写入成功。读的时候同样也是读多数(R)的节点的值,最终保证W+R>N, 那么就能够保证读到的是 最新写入的数据。

Basic Paxos算法

Paxos 算法使用的是基于quorum的无主复制。

基本概念:

  • Client(客户端):负责写入数据。

  • Proposal(提案):节点收到客户端的写入请求后发起提案,将提案发送给其余的W个节点,提案用来驱动整个一致性算法。

    • Proposal Number(提案编号):表示这是提案者的第几轮提议。

    • Proposal Value(提案值):表示这是提案者的提案Value。

  • Proposer(提案者):负责收到客户端写入请求后发起提案并在冲突时进行协调,推动算法运行。

  • Acceptor(接受者): 负责投票接受或者拒绝提案者的提案,超过半数 的接受者都接受了提案,那么提案就被批准。

  • Learner(学习者):不参与决议提案(避免投票人数过多导致投票过程复杂),只学习被批准的提案。

算法规则:

  1. 允许一个节点接受不同的提案,一旦一个值被批准了,未来的提案必须提议相同的提案值.

  2. 接受者会持久化存储:已经接受的最大提案编号(max_n), 已经接受的提案编号(accepted_N), 已经接受的提案值(accepted_Value)

第一阶段:

第一阶段主要是分为Prepare和Promise阶段,提议者收到客户端的请求后选择最新的提案编号n向超过半数的节点发起提案,接受者收到提案后进行响应处理。

目的是发起提案并确保超过半数的节点接受了提案后才做后续的处理。

phrase1_a:

提议者向超过半数节点发起提案,仅传递提案编号(第几轮提案)即可。

phrase1_b:
  • 如果prepare 消息的提案编号 n 大于 之前接受的最大的提案编号

    • 返回Promise消息(表示接受提案)

    • 承诺不会再接受提案编号小于 n 的提案

    • 如果之前接受过提案,将接受过的提案编号和提案值返回给提议者

  • 否则忽略请求或回复拒绝的响应

第二阶段:

如果超过半数的节点接受了提案,那么提议者会将提案值再同步给多数节点,多数节点重新根据规则设置Value

phase2_a:
  • 如果大多数的接受者接受提案:

    • 如果没有收到来自于接收者传递的 提案值

      • 那么本轮的提案值由提议者决定
    • 否则提案值改为收到的来自于 Acceptor 返回的提案值

    • 将确定的ID和Value发送给大多数节点

phase2_b:

  • 对于Acceptor来说,如果收到的提案编号仍然是接受到的最大的提案编号

    • 那么就接受提案,更新提案值
  • 否则不响应