Distributed System 基础(五)协议(Protocol)(上)

1 原子提交(Atomic commit)

在我们分布式系统中存在许许多多的进程,p1,p2,p3...pn,我们希望每一个进程都能够知道他应该执行什么事务,同时,我们也希望每个进程能够保持同步,执行相同的事务,这就叫做提交(commit).如果一个事务被提交了,那么所有进程都将会知道,并且执行操作。例如:维护数据库的每个副本一致。在这个过程中,我们有一个最大的问题,叫做错误(fault),我们可能会有许许多多的错误。错误分两种:

  1. Crash failures:系统停止工作
  2. Byzantine failures:一个拜占庭进程可以做任何事情,甚至是恶意的导致系统失效,这种failure比第一个crash failures还要更糟糕

一个原子提交意味着所有进程同时提交或者不提交。在一个异步系统中,即使存在一个有一个crash failure,一致也是无法达到的(根据FLP原理)。并且对于一部系统从广义上来说,我们也无法判断一个进程到底是执行非常缓慢还是crash failure了。

2 性质

AC 1 所有的进程达成决定(reach decision),那么必然是达成了同一个决定

AC 2 进程不能返回之前的决定

AC 3 只有当所有的进程都投票"yes"是,才能提交(commit)

AC 4 如果不存在failure,并且所有进程全投给“yes”,那么这个决定一定是commit

3 Two-phase commit(2PC)

two-phase commit协议是最简单的原子提交协议,它安全性很好但活跃性不高(即,不是时常在工作)。在这个协议中,我们有两个角色:coordinator和participants。coordinator向所有participants发送投票请求信息,所有的participants发送他们的投票给coordinator。如果是"no"那么participant直接abort,如果是“yes”,则该participant等待coordinator的回应。当coordinator收到所有投票后,如果全是“yes”,则向所有participants发送“COMMIT”消息,如果有“no”,那么它则向投“yes”的participants发送“ABORT”消息。

现在我们知道了two-phase commit的工作原理,但现实生活中往往有故障会发生,那我们来假设一些故障。例如:某个participan并没有收到coordinator的投票请求(vote request),那么它在等待时间结束后,那么它将会ABORT,根据协议,整个系统都将会ABORT。

再如果coordinator并没有成功的发送出decision消息,那么我们将会卡在最后一个阶段,participant并不知道自己到底是该COMMIT还是ABORT。

于是我们有两个解决这个问题的方案:

  1. Cooperative Termination Protocol
  2. Recovery Protocol

第一个方案Cooperative Termination Protocol,当一个participant不知道该做什么的时候(即不知道自己该COMMIT还是ABORT),它向自己知道的其他participants广播询问,如果有知道的则会告诉它coordinator的选择

第二个方案核心思想是:假设一个进程crash了,我们可以通过重启来解决这个crash。为了让进程重启后能够知道之前的状态,我们需要日志来记录,这个日志叫做:DTLOG。总的来说,这个日志的作用就是保存决定:如果participant投票“yes”,那么在发出信息前,必须写入日志。如果投票“no”,那么在发出信息前后写入日志都可以。如果coordinator发送的是COMMIT的话,必须在发送前记录,如果是ABORT的话,则发送前后都可以。

由此,我们又可以得到一个AC:

AC 5 执行任何考虑到failure的算法,在执行的任何时间,当failure被修复,并且一段时间没新failure,那么所有的进程都最终做出决定。

4 Logging

这里将详细描述DTLog的功能及其作用。我们根据以下的规则来使用DTLog,我们将简称Coordinator为C,Participant为P。

  1. 当C发送投票请求时,在DTLog上写Start2PC.包括每个participant的id,并且可以在发送前或者发送后写入log。有趣的是如果你在发送前写入,那么如果你写完后马上就crash了,没来得及发送vote request,那么当你恢复后,你通过查询log,你能发现participant的id名单,所以你的状态是可以恢复的。而如果你选择在发送后写入,结果发送完就crash了,没来得及写入,那么在恢复后你无法在log查找到任何东西,你将会发送ABORT,这样也是安全的。
  2. 如果P投票“yes”则必须在发送前写入DTLog,因为,如果你如果在发送之后写入,那么如果你在发送后立即crash了,没来的即写入log,那么在你恢复后,你讲无法在你的log里查找到你之前投了什么,那么你将会执行ABORT,但是,事实情况却是你有可能投了“yes”,并且所有人投的都是“yes”,此时可能会有别的进程正在执行COMMIT。如果P投票“NO”那么这种情况的话就发送前发送后记录都可以
  3. 如果C决定COMMIT,它必须在发送前在log里写入COMMIT,如果是ABORT则发送前后都可
  4. 在接收到decision后,P要把它写入log
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值