令人迷惑的CAP与ACID用语

令人迷惑的CAP与ACID用语

Consistent-Available-Partition-tolerant】的定义。

ACID & CAP -一个提醒

ACID属性在70年代被确定,然后术语ACID被创造于1983年:

CAP由Eric Brewer猜想于2000年,由Seth Gilbert和Nancy Lynch证明于2002年:

首先,让我们看下全画面

词语

数据库

CAP

迷惑?

事务

一组操作

不使用这个词语和概念

持久化

“一旦事务成功,其对状态的更改,即使系统出现故障也不受影响”[D2]

不使用这个词语和概念

一致性

数据完整性约束(数据类型,关系,…)

对于CAP,一致性是“原子一致性”的简称。原子一致性是个一致性模型,稍后详述

同一个词

不同概念

隔离性

“尽管多个事务并发执行,但看上去好象,对于每个事务T,其它事务要么在T之前、要么在T之后执行”. [D2]

CAP不使用这个词语,但ACID定义的隔离性在CAP词汇中是个一致性模型

不同的词

相同概念

原子性

所有更改要么发生,要么全部不发生

对于CAP,原子性是个一致性模型,在CAP证明中被使用

同一个词

不同概念

可用性

概念不经常使用,如果有,定义可能不同于CAP中的,即可用性也许不要求所有的非故障节点都响应

“被系统中非故障节点接收到的每个请求必须产生一个响应”[C2]

同一个词

相同概念

不同定义

分区容错性

概念不经常使用,如果有,定义与CAP中一致

两组节点被分区时,它们之间的所有消息都将丢失

现在,让我们深入一些细节:我们将发现,有一些额外的迷惑源自分布式数据库。

事务(只存在于ACID)

一个事务是一组操作。这组操作的任何一个可以读写多个数据。ACID是给予这组操作相同的属性,就好像它是一个唯一的操作。这不是CAP的目标。CAP是关于多个操作使用相同数据的(可能的)属性,这个属性可能是复制。

持久化(只存在于ACID)

“一旦事务成功,其对状态的更改,即使系统出现故障也不受影响”意思很清楚的,但把故障描述留给物理部署处理。主要取决于冗余:单节点多磁盘 及/或 多节点 及/或 多中心。 “幸免于”并不暗示任何可用性的概念: 它的意思是它至少可以稍后恢复数据。

CAP本身没有提及持久化。CAP中的持久化是隐式的:CAP是有关分区,而不是节点故障。

CAP中的可用性

在CAP中,可用性意味着,若系统被分区,所有的非故障节点继续服务于请求。许多分布式系统认为它们是具有可用性的,这些系统当出现分区时,一部分非故障节点继续服务于请求。这样的系统并非具有CAP中的可用性。

CAP中的一致性与CAP中的原子性

CAP中的一致性是原子一致性的简称。原子一致性是一个一致性模型。一致性模型描述系统中各操作以什么样的顺序执行。有哪些操作因系统而异,例如,若要定义一个事务处理系统的一致性模型,那么“commit”就应是操作之一。用于证明CAP理论的分布式共享内存模型(Lynch定义于[V6]),使用的操作有read、write、ack。

选择一个一致性模型远不那么简单。有很多的一致性模型,因为存在许多可能的权衡:

·一致性模型易用性如何。这也取决于应用本身:某些一致性模型可能对一些应用是易用的,而对其它应用就不易用。

·内存模型的实现是否高效。这也取决于硬件和物理部署。

用于ACID与CAP的一致性模型其实是简单的:

·顺序一致性,由Lamport定义[V9]:“程序的行为好像是,所有处理器的内存访问是交叉的,然而是按顺序执行的。”

·原子一致性(也被称为线性一致性)是顺序一致性加上实时约束:“与顺序一致性不同,线性一致性假设在所有处理器之间存在全局时间的概念。各操作被间隔所建模,间隔是由调用和响应之间一段时间组成,每个操作假定是在间隔内的某点瞬间生效。”[V7]

一致性“是原子一致性:它只是个简称。CAP中的原子性(操作顺序执行)与ACID中的原子性(全部完成或什么都不做)根本就不是一件事。

ACID中的一致性

ACID中的一致性与数据完整性相关。例如:通常可能在SQL数据库中实现这样的规则:

·字段不能为空值

·字段必须是数字型

·字段是对另外一张表中字段的引用

数据库不允许提交违反约束的事务。这就是ACID中的一致性约束。定义与CAP的不相同。

重要的是要记住,一个数据库(SQL或非SQL),并未实现所有的一致性约束。

ACID中的原子性

或者-什么都没有”的行为十分直观:例如,有这样个事务,用伪代码模拟两账号间转账:

begin

val1 = read(account1)

val2 = read(account2)

newVal1 = val1 – 100

newVal2 = val2 + 100

write(account1, newVal1)

write(account2, newVal2)

commit

原子性是说两账号都被更新或者没有一个被更新。如果写入账号1成功,然后写入账号2失败,这两个写入操作将被回滚。

然而,ACID中的原子性并不说明这个事务隔离于其他事务。换句话讲,你可以宣称自己达成ACID中的原子性,甚至当:

·在事务提交前,写入的值能被其它事务所见。

·读到的值可能是被其它事务正修改的。若多次读取同一个值,可能会得到不同的结果。

例如,使用上面提到的事务,你能预期很多SQL数据库的行为:

·开始,账户1有1000,账户2是0

·同时并行两笔转账(如上面代码)

·当你预期账户1是800、账户2是200时,你却从账户1上看到是900。

这是因为在ACID中,原子性不同于隔离性:原子性/全部完成-或-什么都不做,,不代表是被隔离的。

Isolation隔离性

你并不一定会从此拥有更美好的人生,

令人迷惑的CAP与ACID用语

相关文章:

你感兴趣的文章:

标签云: