Distributed System Transaction —— 各种一致性(Consistency)的讨论

概述

Distributed System Transaction —— 什么是线性一致性(Linearizability)?一文中,介绍过一致性这样的概念,对于一致性,简单的分类是“强一致”和“弱一致”,但这只是一种统称,实际上可以分为:(弱->强)

  • 最终一致性(Eventual)
  • 因果一致性(Casual)
  • 顺序一致性(Sequential)
  • 线性一致性(Linearizable)

所以强一致是包含顺序和线性一致性的,其余两者是弱一致性。在强一致性的系统中,对外表现是一致的,但是可能产生相对较高的延迟;而弱一致性则相反。
在这里插入图片描述
在达成一致性的过程中,可能使用到的方式叫做共识,比如Raft共识协议能够达成强一致,又比如POW算法能够达到弱一致。

当然也有一些达成一致性的过程中的算法一般并不称为共识,比如Google的Spanner所采用的True Time API+Snapshot Isolation ,也能够达成强一致里的线性一致性。

其实在很多地方我们会看到一致性这样的说法,比如ACID中的Consistency、CAP理论里的Consistency。

  • ACID 中的一致性是指数据库的一致性约束,ACID 一致性完全与数据库规则相关,包括约束,级联,触发器等。在事务开始之前和事务结束以后,都必须遵守这些不变量,保证数据库的完整性不被破坏,因此 ACID 中的 C 表示数据库执行事务前后状态的一致性,防止非法事务导致数据库被破坏。比如银行系统 A 和 B 两个账户的余额总和为 100,那么无论 A, B 之间怎么转换,这个余额和是不变,前后一致的。
  • CAP 理论中的 C 也就是我们常说的分布式系统中的一致性,更确切地说,指的是分布式一致性中的一种: 线性一致性(Linearizability),也叫做原子一致性(Atomic consistency)。

一致性需要考虑的几个问题


为什么会出现一致性
我们最常用于讨论的便是复制状态机(Replicated state machines)的一致性问题,比如 etcd, zookeeper,当进程 A 执行 set x 3 时,进程 B 是否能在 A 执行完成后立即读到 x 的新值


一致性需要考虑的元素
要理解分布式一致性,先来谈谈分布式中几个必要的概念: 时间,事件,和顺序。

  • 考虑节点时间的不一致(延迟、漂移)
  • 考虑事件(Read或者Write、发送或者接收)
  • 考虑事件顺序

各种一致性

顺序一致性

虽然线性一致性强于顺序一致性,但是由于顺序一致性出现的早(1979年),而线性一致性是在其基础上的加强,所以先介绍顺序一致性。Leslie Lamport 在1979年提出了Sequential Consistency, Leslie Lamport的定义如下:

A multiprocessor is said to be sequentially consistent if the result of any execution is the same as if the operations of all the processors were executed in some sequential order, and the operations of each individual processor appear in this sequence in the order specified by its program.[How to Make a Multiprocessor Computer That Correctly Executes Multiprocess Programs by Leslie Lamport ,1979]

这个定义中,需要注意的是 MultiProcessor和 Individual Processor,这是讨论这个定义的大前提,也就是讨论的一个事件在整体和部分上通过重排如何表现的问题。
其定义为:

如果一个并发执行过程所包含的所有读写操作能够重排成一个全局线性有序的序列,并且这个序列满足以下两个条件,那么这个并发执行过程就是满足顺序一致性的:

  • 条件I:重排后的序列中每一个读操作返回的值,必须等于前面对同一个数据对象的最近一次写操作所写入的值
  • 条件II:原来每个进程中各个操作的执行先后顺序,在这个重排后的序列中必须保持一致

解释这段话,可以用一个“调度器”的例子:将整个分布式系统想象成一个调度器,将多个进程 的请求看做是多个FIFO请求队列, 调度器依次处理队列中的请求,并在多个队列中不断切换。

下面来看一个例子,原本各个部分的执行顺序是这样的:
在这里插入图片描述
而通过某种共识算法后,重排序如下:
在这里插入图片描述
显然这个结果是满足顺序一致性的。再来看一个例子:
在这里插入图片描述
如果重排序后是这样的:
在这里插入图片描述
我们可以发现,4和5的最近一次写操作都是B值,这显然不满足顺序一致性的要求。


你可能会问,顺序一致性为什么会这样定义呢?这个定义的初衷是什么?

我们可以试着这样理解:首先,重排成一个全局线性有序的序列,相当于系统对外表现出了一种「假象」,原本多进程并发执行的操作,好像是顺序执行的一样。本文前面提到过,理想情况下,分布式系统应该“表现得像只有一个副本”一样。顺序一致性正是遵循了这种「系统假象」,系统对外表现就好像在操作一个单一的副本,执行顺序也必然是可以看做顺序执行的。而条件I规定了系统的表现是合理的(即合乎逻辑的);条件II则保证了以任何进程的视角来看,它所发起的操作执行顺序都是符合它原本的预期的。总之,一个满足顺序一致性的系统,对外表现就好像总是在操作一个副本一样。

线性一致性

线性一致性的定义[5],与顺序一致性非常相似,也是试图把所有读写操作重排成一个全局线性有序的序列,但除了满足前面的条件I和条件II之外,还要同时满足一个条件:

如果一个并发执行过程所包含的所有读写操作能够重排成一个全局线性有序的序列,并且这个序列满足以下两个条件,那么这个并发执行过程就是满足线性一致性的:

  • 条件I:重排后的序列中每一个读操作返回的值,必须等于前面对同一个数据对象的最近一次写操作所写入的值
  • 条件II:原来每个进程中各个操作的执行先后顺序,在这个重排后的序列中必须保持一致
  • 条件III:不同进程的操作,如果在时间上不重叠,那么它们的执行先后顺序,在这个重排后的序列中必须保持一致

所以对于下面的例子:
在这里插入图片描述
线性一致的结果如下,并不是简单的将事务的Start做了排序,还要满足结果的正确。
在这里插入图片描述

因果一致性和最终一致性

因果一致性在 Distributed System Clocks分布式系统时钟解决方案有介绍,不做赘述。

而最终一致性,可以在BASE中去做了解,可以参考:Java架构直通车——多数据源下事务最终一致性解决方案

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值