分布式一致性协议

分布式一致性协议
Amir H. Payberah  《Distributed Systems Consensus》
Amirkabir University of Technology

问题是什么?
为保证分布式系统的高可靠和高可用性,数据在系统中一般存储多个副本。当某个副本所在的节点出现故障时,分布式系统能够自动将服务切换到其他的副本,从而实现自动容错。同一份数据的多个副本中往往有一个副本为主副本,其他为备副本。从一份数据的角度讲,主副本所在的节点为主节点,备副本所在的节点为备节点。但在整个系统范围上看,每个节点即是主节点,也是备节点。

                  分布式一致性协议_第1张图片
由于同一份数据在整个系统中存在多个副本,因此需要解决如何保证多个副本的一致性问题,以及当主节点出现故障时,如何从多个备节点中选举新主节点的问题。
为解决这些问题,需要做到:
  • 使主副本数据状态是确定的(状态机)
  • 复制主副本数据到其他备节点
  • 确保数据状态的改变以相同的顺序被复制到备节点上,保证得到正确的数据副本。
采用什么协议成了关键点。

一致性协议问题
多个节点间的一致性协议过程,简单来讲就两步:
  • 某些节点提出建议值( 或者行动),并发送给其他节点;
  • 所有节点必须决定接受还是拒绝这个建议。
但是,理解是丰满地现实却是骨感......:
  • 并发进程时间、事件和输入的不确定性;
  • 机器/进程的故障与恢复,通讯渠道的故障与恢复。

一致性协议要求
1. 安全性
  • 有效性:在被提出的建议值中,只有一个可以被选定
  • 一致性: 没有任何两个确定的节点选择不同的值
  • 完整性:一个节点最多只能选择一次
2. 存活性
  • 可终止性: 每个确定的节点,最终都会选择一个值

分布式系统协议:可能的解决方案
             
  • 两阶段提交(2PC)协议
  • Paxos协议
(最近Raft协议又在坊间流传、使用,据传说比Paxos协议简单,当然有效是必须地。具体情况,我们接下来再聊。)


两阶段提交(2PC:The Two-Phase Commit)

两阶段提交(2PC)问题
  • 此问题首先是在数据库系统遇到;
  • 假设数据库系统正在更新某些复杂的数据结构,此数据结构由保存在多台机器上的多个部分组成;
  • 系统模型:
    • 并发进程时间、事件和输入的不确定性(异步系统);
    • 机器/进程的故障与恢复,通讯渠道的故障与恢复。

一个直观的例子
               分布式一致性协议_第2张图片
  • 你想跟三个朋友星期二下午6点组织郊游, 只有所有人都同意才能出行
  • 你怎么做呢?
    • 打电话给每个人,问他们星期二下午6点是否可行?(投票阶段voting phase
    • 如果所有人都觉得时间可以,打电话给每个人,告诉他们事已确定;(提交commit
    • 如果有人说没时间去不了,打电话给其他三人,告诉他们出行取消。(中止abort
  • 关键细节:
    • 当你打电话给每个人询问时,凡是承诺promised)周二下午6点能行的人,必须留出时间must reserve that slot);  
    • 你需要记下这些决定remember the decision),然后在提交/中止阶段告诉每个人 tell anyone):谁哪没有达成。
  • 这正是两阶段提交是如何工作的。

两阶段提交(2PC)中的角色
  • 协调者Coordinator(事务管理器Transaction Manager
    • 开始事务;
    • 负责提交/中止(commit/abort)事务。
  • 参与者Participants(资源管理器Resource Managers)
    • 分布式事务中的数据服务器。

两阶段提交(2PC)算法
阶段1 - 准备prepare阶段
  • 协调者Coordinator) 询问每个参与者participant能否提交canCommit)?
  • 参与者Participants) 必须为提交commit) 数据修改到持久化存储storage)做好准备,然后才能回复“yes“。
    • 锁定Lock) 涉及到的数据对象。
    • 参与者在对协调者Coordinator) 能否提交canCommit)询问回复“ yes”后,不允许not allowed)引发事务中止abort)。
  • 这时事务的结果还是不确定的uncertain) ,这种状态一直持续到最终事务提交doCommit)或者事务中止doAbort)。
    •  其他参与者Other participants) 仍有可能引发中止abort)。   
阶段2 - 提交commit阶段
  • 协调者coordinator 汇集所有投票all votes)。
    • 如果全体一致地投票“ yes”(unanimous yes), 则引发提交。
    • 如果任一参与者投票 no”(any participant voted no), 则引发中止。
  • 一旦所有参与者participants)全部投票完毕,事务的命运由协调者 coordinator自动atomically)决策。
    • 协调者使用持久化存储permanent storage)记录最后决策。
    • 然后向参与者广播broadcasts)决策:事务提交 doCommit) 或者事务中止doAbort)。
两阶段提交(2PC)事件时序
            
分布式一致性协议_第3张图片
两阶段提交(2PC)的恢复
主要的恢复类型
  • 在处理超时后恢复。
  • 在系统崩溃重启后恢复。
  • 在一个弹性的异步网络环境中,不能区分上面的这两个情况。

超时处理
  • 避免进程永久阻塞情况发生
  • 两种阻塞场景:
    •  协调者Coordinator ) 等待参与者 participants的投票。
    • 参与者(Participant)等待最终决策  final decision)。

协调者超时处理
     
  • 如果B投票no”,协调者能否单方面中止事务?
  • 如果B投票yes“,协调者能否单方面中止/提交事务?
    • 协调者等待参与者投票
    • 参与者等待最后的决策
    • 协调者超时后中止,并且发送事务中止doAbort)给参与者。

参与者超时处理
            
  • 如果B与事务管理器(协调者)间超时,并且已经回复协调者投票” yes“,那么执行终止协议
  • 简单终止协议Simple protocol): 参与者保持阻塞remained blocked) ,直到与协调者重新建立通讯。
  • 协作终止协议Cooperative protocol): 参与者发送一个决策请求decision-request)消息给其他参与者other participants)。比如:
    • B发送状态消息给A
    • 如果A已经从事务管理器(协调者)收到事务提交/事务中止(commit/abort)指令, ...    
    • 如果A还未投票给事务管理器,A如果还没决定,那它也没法帮到B,A如果单方面决定abort,那它可以回复B一个aboort,B执行相应操作。
    • 如果A已经投了yes,但还未收到事务管理器的决定,那A无法帮到B;
      如果A已经投了no,那A可以回复B一个abort,B执行相应操作。

崩溃处理与恢复
  • 所有节点必须把协议进展记入日志log protocol progress)。
    •  参与者Participants):prepared->uncertain->committed/aborted
    • 协调者Coordinator):prepared->committed/aborted->done 
  • 如果已经决策提交事务commit is decided),所有节点不能再退出( cannot back out )
  • 协调者Coordinator)崩溃,恢复时: 
    • 如果从磁盘日志中未找到提交no commit ),那么进行事务中止过程aborts)。
    • 如果从磁盘日志中找到提交( commit),  那么进行事务提交过程(commits)。 
  • 参与者Participant) 崩溃: 
    • 如果找到事务提交commits)或者事务中止aborts)记录,表明在崩溃前已经达成决策,进行相应处理即可。
    • 如果从磁盘日志中未找到yes投票no yes),那么进行事务中止过程(aborts)。
    • 如果从磁盘日志中找到yes投票 yes),那么运行终止协议(termination protocol )来达成决策。  

 2PC容错局限性
  • 即使启用了恢复机制,两阶段提交也达不到真正的容错fault-tolerant),因为当有一个(或几个)机器故障fail),可能会被阻塞blocked )
  • 阻塞意味着故障期间处理不会有进展。(not make progress during the failures)。
  • 来个场景秀一下? 

2PC阻塞场景
           分布式一致性协议_第4张图片
  • 事务管理器发达事务提交doCommit决策到A,A收到后进行提交处理,然后事务管理器和A都死掉(both TM and A die)。
  • B、C、D同样也已经回复投票yes, 并且锁定了locked)它们本身的一些互斥锁,那么现在需要等待事务管理器或A活过来。
  • 没有确定的决策,他们不能进行恢复动作(cannot recover),直到事务管理器或者A重新在线。
  • 这就是为何两阶段提交(2PC)被叫做阻塞式协议(blocking protocol):2PC是安全的,但不是具有活性的。 

Paxos协议

唯一已知完全安全(completely-safe) 巨大活性largely-live)的一致性协议.

Paxos协议中的角色
  • 提议者(Proposers
    • 提出提案值供投票者考虑。
  • 投票者(Acceptors) 
    • 考虑提议者提出的提案值。
    • 回复一个批准/拒绝决策。
  • 学习者(Learners  
    • 学习已经通过的提案值。
  • 一个节点能扮演一个以上的角色

单个提案Proposal,单一投票者(Acceptor)
           分布式一致性协议_第5张图片
  • 只使用一个投票者acceptor)。
    • 收集多个提议者Proposers提案 proposals 
    • 决定通过的值,告知其他所有人。
  • 听起来熟悉吗?
    • 两阶段提交2PC)。
    • 投票者(acceptor)故障 协议阻塞

单个提案(Proposal),多个投票者(Acceptor)
           分布式一致性协议_第6张图片
  • 单一投票者不能充分地容错
  • 让我们设置多个投票者acceptor)。
  • 必须达成一个决策,如何做
  • 决策 = 被大多数批准的值
  • 原则1:一个投票者(acceptor)必须批准所收到的第一个提案(proposal)
    • 原则1a:当且仅当投票者(Acceptor)没有收到编号大于n的Prepare请求时,投票者(Acceptor)批准编号为 n的提案(Proposal)。

  多个提案Proposal,多个投票者(Acceptor)                  
          分布式一致性协议_第7张图片
  • 如果有多个提案multiple proposals没有提案no proposal能得到多数票majority
  • 如图,3个提案,每个可能获得1/3的投票者。
  • 解决方案:投票者能批准多个提案accept multiple proposals,通过一个唯一的提案编号unique proposal number区分。

多个提案Proposal的处理
  • 所有被通过的提案chosen proposals)必须是相同的提案值the same value)。
  • 原则2:如果一个提案的值v被通过,那么之后被通过的每个更高编号的提案,必须具有相同的提案值
    • P2a:一旦一个值v被通过,那么之后任何投票者(Acceptor)再批准的值必须是v。
    • P2b:一旦一个值v被通过,那么以后提议者(Proposer)提出的新提案必须具有值v。
    • P2c:如果一个编号为 n 的提案具有值v,那么存在一个多数派,要么他们中没有人批准过编号小于 n的任何提案,要么他们进行的最近一次通过具有值v。

Paxos算法
  • 阶段1a - 准备(Prepare)
    提议者(Proposer) 选择一个提案编号 N,并将包含了该编号的Prepare(N)请求,发送给所有投票者(Acceptor) 中的一个多数派(majority);
  • 阶段1b - 承诺(Promise)
    投票者(Acceptor) 收到 Prepare (N)消息后,当N大于所有它以前承诺过(promise)或收到Preapare请求的编号
    •  承诺不再批准编号小于N的提案,
    • 发送响应promise(N,U)U是上次批准的最大编号提案(如果有的话)。
  • 阶段2a - 请求批准(Accept!)
    如果提议者(Proposer) 收到了多数派的响应,向这些回复 Prepare(N) 请求的投票者(Acceptor),发送Accept(N,V)请求,V是收到的promise响应中最大编号提案的值,如果没有promise包含提案,那么可自由定值。
  • 阶段2b - 批准(Accepted)
    如果N大于等于任何已经承诺过(proimise)的提案编号
    • 批准这个提案
    • 发送一个accepted通知给提议者或学习者。

分布式一致性协议_第8张图片

Paxos示例

分布式一致性协议_第9张图片



Paxos安全性
         分布式一致性协议_第10张图片
  • 如果编号为n的提案包含的值v已经被通过,在第二轮(2a、2b)发出的后续更大编号提案,必须包含相同的值v
  • 决策 = 多数派 (任意两个派至少共享一个成员)。
  • 因此,第一轮(1a、1b)有了决策后, 随后的一轮(2a、2b)中至少有一个投票者已经批准过值v
  • 现在假设我们的说法是不正确的,在后面第二轮(2a、2b)中有一个编号为m首次提案(m晚于n),提议中的值是w等于v
  • 这是不可能的,因为如果这个提议者P可以用值w启动第二轮(2a、2b),说明它已经让多数派批准过一轮提案mm>n)。所以,会有矛盾的结论:
    • v 未被决策通过,与
    • v 被P提案过
  • 因此,一旦有多数派批准过值v ,就不会被改变。


Paxos活性
............


Paxos的实现
  • Google:Chubby
  • Yahoo:Zookeeper
  • .........

原文来自于:www.slideshare.net 《Distributed Systems Consensus》 PPT
译          者:歪脖大肚子Q

你可能感兴趣的:(数据库,分布式)