分布式一致性概述

本文依照张铁蕾老师的文章条分缕析分布式:到底什么是一致性?,梳理总结分布式一致性相关的概念。

分布式一致性概念澄清

一致性的相关概念:

  • consistency:ACID、CAP定理中的C均为consistency但真实含义不同
  • consensus:PAXOS等分布式一致性协议中的C,翻译为共识更为准确
  • 强一致性牵扯到CAP定理或者分布式事务,强一致性与CAP定理确实关系密切,但与分布式事务的关系不知从何而来

ACID中的一致性

ACID是数据库事务的四个特性,分别是原子性、一致性、隔离性和持久性。

ACID中的一致性,是指任何一个数据库事务的执行,都应该让数据库保持一致的状态。

  • 是对于整个数据库的一致状态的维持,抽象来看,对数据库每一次事务操作,其状态就发生一次变化。相当于把数据库变成了状态机,只要数据库的起始状态是一致的,并且每次事务操作都能保持一致性,那么数据库能始终保持在一致的状态上。
  • 而“不一致的状态”是业务层规定的某种规则,所以ACID中的一致性,体现了业务逻辑上的合理性,并不是由数据库本身的技术特性所决定的。

保证ACID的一致性

那么为了让事务总能保证ACID中的一致性,至少要考虑两个方面:出错情况(failure/error);并发行为(concurency)。

出错情况

出错情况一般分为两种:业务逻辑本身的错误;业务逻辑意外的各种软硬件错误。

针对业务逻辑本身的错误,需要正确的业务逻辑,以及正确的编码来保证。

针对出业务逻辑之外的错误,则需要ACID中的A来保障,即原子性保障事务执行要么全部成功,要么全部失败。

并发行为

针对并发访问同一数据的情况。需要ACID中的隔离性来保证。对于并发执行的多个事务进行合理的排序,保障不同事务的执行互不干扰,隔离性能够让并发执行的多个事务看起来像是按照先后顺序执行的一样。

ACID一致性总结

  • ACID中的一致性,是一个很偏应用层概念,与ACID中的原子性、隔离性、持久性有很大的不同。AID都是数据库本身所提供的技术特性,而C则是由特定的业务场景规定的。
  • ACID一致性依赖数据库的原子性和隔离性,同时应用层必须保证业务逻辑本身正确。
  • ACID中的一致性与分布式没有直接的关系,唯一关联为:在分布式环境下,其依赖的数据库原子性和隔离性更难实现。

分布式事务与共识算法

consensus problem 共识问题:分布式系统中的一个十分基础且核心的问题,表示如何在分布式系统中的多个节点之间就某件事达成共识。

通常讲到的分布式一致性协议、分布式一致性算法,一般来说就是解决这里的共识问题的算法。这些算法或者协议中经常包含Paxos之类、也可能包括两阶段提交协议(2PC)或者三阶段提交协议(3PC)。

Paxos、2PC、3PC区分:Paxos是解决分布式共识问题的通用算法,允许每个节点提出自己的提议(proposal),Paxos能够不借助任何中心化的节点,保证各个节点之间对于提议最终达成一致。2PC、3PC是为了解决分布式事务提交问题的。

2PC、3PC产生的背景:事务本身和分布式没什么直接关系,在分布式环境下,事务的ACID特性更难实现。分布式事务下的ACID中的原子性拓展到全部节点,要求参与事务的全部节点要么全部执行Commit或者要么全部执行Abort。即参与事务的全部节点需要在“执行Commit还是Abort”这一点上达成一致。这个问题就是原子提交问题(Atomic Commitment Problem),而能解决原子提交问题的算法,成为原子提交协议(Atomic Commitment Protocal,ACP),2PC、3PC属于原子提交协议两种不同的具体实现。

也就是说为了分布式事务在执行的过程中,由于原子性的要求,所有参与事务的节点必须统一Commit或者Abort。

原子提交问题与共识问题的关联:

  • 共识问题(consensus problem):解决分布式系统多个节点就某个协议达成共识,只关注没有发生故障的节点是否达成共识
  • 原子提交问题:解决参与分布式事务的所有节点在“执行commit还是abort”这一点达成共识。
  • 原子提交问题是共识问题的一个特例。

共识问题与原子提交问题的区别在于是多个节点还是所有节点达成共识,这个细微的差别使两类问题变成完全不同的问题。原子提交协议必须保证在参与分布式事务的所有节点(包括故障的节点)上对于“执行Commit还是Abort”达成共识,避免事务发生“部分执行成功”这样违反ACID原子性要求情况。故障节点在恢复之后,它的决策(Commit或是Abort)必须与其它所有节点保持一致。

故障发生时原子提交协议并不会阻塞,其根源在于Abort和Commit并不是对等的决策,只要故障发生其他节点都选择Abort就好了,等宕机节点恢复之后选择Abort处理,这样参与分布式事务的所有节点对于“执行Abort还是Commit”达成了一致,正因为如此使2PC、3PC看似简单的协议实现起来并不容易。

原子提交问题被抽象成了一个新的一致性问题,称为uniform consensus问题,是比consensus problem更难的问题,要求所有节点达成一致。

总结:

  • consensus problem,解决如何在分布式系统中的多个节点之间就某个提议达成共识,只关注没有发生故障的节点。
  • 在分布式事务中,ACID中的原子性,引出了原子提交问题,解决分布式节点如何在“执行Abort还是Commit”达成共识。
  • Paxos和解决拜占庭问题的算法,解决的使consensus问题;2PC、3PC解决的是一个特定的uniform consensus问题。

CAP与线性一致性

CAP分别代表了分布式系统中的三个特性,一致性(Consistency)、可用性(Availability)和分区容错性(Partition-tolerance)。任何一个分布式系统只能同时满足三个特性中的两个。

其中一致性在原始论文中指线性一致性(linearizability)。在一个并发执行的环境中,不同的操作之间可能是有严格的先后关系的(一个操作执行结束之后另一个操作才开始执行),也可能是并发执行的(一个操作还没执行结束,另一个操作就开始执行了);如果能够把所有操作排列成一个「合法」的全局线性顺序,那么这些操作就是满足线性一致性的。

对于一个分布式存储系统来说,线性一致性的含义可以用一个具体的描述来取代:对于任何一个数据对象来说,系统表现得就像它只有一个副本一样。如果系统对于每个数据对象真的只存一个副本,那么肯定是满足线性一致性的。但是单一副本不具有容错性,所以分布式存储系统一般都会对数据进行复制(replication),也就是保存多个副本。这时,在一个分布式多副本的存储系统中,要提供线性一致性的保证,就需要付出额外的成本了。

分布式事务处理的并不是同一个数据对象的多个副本的问题,而指的是将针对多个数据对象的各种操作组合起来,提供ACID的特性。将分布式事务看成是强一致性的保证,猜测可能实际上指的就是ACID的原子性。总之,「强一致性」这个词很容易产生误解,所以建议谨慎使用。

参考资料

https://mp.weixin.qq.com/s/qnvl_msvw0XL7hFezo2F4w

Author: nopainanymore
Link: http://nopainanymore.me/Overview-Of-Distributed-Consensus/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
wechat