我看到有 V 友发这个问题,但我看到有说数据一致性,这个应该没错?各节点数据的一致性会有延缓,这里强调的是数据相同。
但我以往在网上看到的好像都是讲的分布式事务相关的最终一致性,也就是比如我在一个系统扣款,我要在另外一个系统加钱,解决方案有 2pc,tcc,基于消息队列,补偿,最后还可以人工对账。这里强调的是扣钱加钱这两个动作最终一致,数据最终也是“一致“?
1
dilu 2020-04-28 09:28:05 +08:00 2
假设你从 A 账号转 100 块给 B 账号,由于 A 跟 B 在不同的数据库实例,无法使用事务
因此你的业务变成,A 扣 100,记录这笔流水日志,发送消息给队列 B 这里收到队列消息加 100 给 B 账号 那么最终月底对账的时候,你从流水日志里面反推,看看 B 有没有加上这 100 加上了就是最终一致性 没加上 说明一致性没有保证到 |
2
vindurriel 2020-04-28 09:31:36 +08:00 via iPhone 1
就是有一段时间不一致 最坏情况要另行定义 你说的几种方案里 2pc 算是强一致的 其他都是最终一致
问题是很多所谓具有最终一致性的系统 因为设计或实现的缺陷 在某些情况下是最终不一致的 |
3
kirch 2020-04-28 09:46:30 +08:00 2
一致性要求分布式系统里一旦写入数据,每个节点都更新并返回同样的结果,但是根据 cap 定理,一致性,可用性,分区容错性,三者只能保证 2 个,一般都优先保证可用性,分区容错性,最终一致性就是妥协的结果,一旦写入数据,可以过段时间,只要最终每个节点都更新并返回同样的结果就可以了
|
4
beiping96 2020-04-28 10:58:05 +08:00 1
redis 集群:最终一致性
etcd 集群:强一致性 |
5
lewis89 2020-04-28 11:15:27 +08:00 2
强奸-->坐牢 8 年
强奸-->逃逸 10 年-->坐牢 8 年 ..结果一致就行了.. 就这么简单 |
7
liprais 2020-04-28 11:28:08 +08:00 1
最终一致性就是没有一致性
|
9
no1xsyzy 2020-04-28 11:52:05 +08:00 1
@yeqizhang #8 并不是主动延迟,而是相对来说放弃一部分一致性来更多地实现三难的其他两方面。
总体上来说还是 ASAP,但你知道,所谓 ASAP 就是没有期限。 |
10
EmdeBoas 2020-04-28 11:53:35 +08:00 1
https://zhuanlan.zhihu.com/p/47445841
- 单机场景一致性主要看并发隔离 - 分布式场景一致性主要看怎么获得全序关系 一致性门道很多,不系统性的学习根本就弄不清楚的;可以看看 DDIA 这本书 |
11
iugo 2020-04-28 12:25:28 +08:00
当我从桌上拿走一个苹果, 如果一个人的视觉暂留是 1 分钟, 那么在这一分钟内, 他都以为苹果还在, 但最终, 他会看到, 苹果不在桌上了. 他的认识与这个世界实际发生的事情, 最终一致了.
|
12
bottleimp 2020-04-28 12:27:50 +08:00 via iPhone
看看就行了,因为没有哪个最终一致性会跟你明确说多久达到一致。
|
13
luckyrayyy 2020-04-28 12:32:03 +08:00
这个概念是相对于强一致性的吧。
强一致性就是任何时间绝对一致,如果不一致就宁可不给你结果。 最终一致性就先给你结果,临时不对的结果也不要紧,隔一段时间会把结果修正,保证最终一致。 |
14
Aresxue 2020-04-28 12:34:03 +08:00 1
不要弄混 ACID 中的 C 和 CAP 的 C,前者的重心在于系统整体的一致性, 后者指的是多个副本之间的一致性
|
15
sioncheng 2020-04-28 12:41:23 +08:00 1
两个独立运行都系统,A 系统做一个变动,B 系统也做一个变动,它们要么都成功要么都失败,称为分布式事务(一致性是事务的一个特征);但是,这个同时成功或者同时失败在分布式系统里实现起来很困难或者会导致整个系统不高效(比如,整个系统的 TPS 太低),所以有一些其他方法来简化实现和提高整个系统的效率,允许在一定的时间范围内(这个时间范围对于计算机系统来说是比较明显的,比如 1 分钟,但是,对于很多业务场景来说,这个时间差是可以接受的,) A 、B 相继成功或者失败,称为最终一致性。
|
16
yeqizhang OP @Aresxue 我觉得你讲到重点了!!所以我就觉得大家讲了两方面,一般都是解释分布式事务这块,但我觉得对于分布式事务的用 acid 的 C 来讲就不太正确
|
18
lhx2008 2020-04-28 12:51:19 +08:00 via Android 1
两阶段提交,要么成功要么失败那是原子性,事务的一致性通常是事务并发不出问题(有很多个级别),主从数据库集群的一致性本质上是从库复制延迟的问题,只要复制延迟不是 0 就是最终一致性
|
20
EmdeBoas 2020-04-28 13:35:35 +08:00 1
@yeqizhang 14 楼说得并不对,理解太浅显
ACID 里面的 C 定义非常模糊,与业务定义有关,ACID 这几个概念就不正交;单机数据库谈论 ACID 比较多,AID 是对 C 的约束 CAP 里面的 C 也不是指什么副本一致,而是指线性一致性(也就是大家谈论的强一致,但其实大部分人自己是说不清楚什么是强一致的) 还是去看书吧,这个需要扎实的理论基础 |
21
se77en 2020-04-28 14:41:05 +08:00 2
@EmdeBoas 补充一点,Paxos 和 Raft 这种都属于共识协议,一致性( consistency )和 共识( consensus )并不是同一个概念。
|
22
yeqizhang OP @se77en 又学会一个名词,涨知识了。我觉得你和那个大神谈论的都是比较高深一点的,业务上的分布式事务的一致性是不是有所不一样呢?
|
23
xuanbg 2020-04-28 16:16:24 +08:00
首先要明确一点:一般业务系统是不可能通过实现分布式事务来保证一致性的。
业务系统不同于数据库,因为对于数据库来说,所有的数据都是抽象的,对于数据的操作也就是 select insert update delete4 个命令。而业务对于业务系统来说是具体的,对业务的操作也并不能抽象为增删改查 4 个接口。所以在业务层面实现 2pc 、3pc 事务是天方夜谭,根本不具备可操作性。 |
24
xuanbg 2020-04-28 16:22:48 +08:00
@sioncheng A 失败了就没 B 的事了,A 成功了则 B 必须成功。至于 B 在多长时间内成功,肯定是越短越好,但如果这个时间比较长,那也必须接受。反之亦然。
|
26
22yune 2020-04-28 18:15:53 +08:00 1
分布式事务的一致性还是事务的一致性,即业务层面定义的一致性。分布式事务相对与单机事务的难点是:因通信不稳定,参与事务的各个‘进程’如何对状态达成一致。这是个共识问题。
至于 CAP,通常网络 P 很可能发生,无法避免(看到有人说谷歌自建网络非常稳定,不会出现 P )。所以只能在 CA 上做权衡,C 强一点,A 就弱一点。CA 好像是某个概念(延迟?)的一体两面。建议参考 jepsen.io/consistency,https://www.zhihu.com/people/zhangshuai89/posts |
27
dzdh 2020-04-28 18:45:33 +08:00
@sioncheng 最终一致 最粗暴的是共识系统选 leader,以 leader 的结果为准。
首先之所以会出现这样的场景主要是长时间没有获得到其他 S 的应答,那么通常也就是网络问题。以 leader 最终结果为准,其他 S 成功了 leader 失败了那么记为失败。 |
29
sioncheng 2020-04-28 21:11:22 +08:00 1
|
30
yeqizhang OP @sioncheng 嗯,是有两种场景。一种是分布式数据库之类如 zk 需要 leader 来协调数据一致性的系统,这应该属于 cap 中 C 。另一种是分布式业务系统中一个事务需要在多个节点中处理的最终一致性问题。我之前更多的了解是分布式业务系统的事务场景,所以我看到大家解释最终一致性有两种回答就比较疑惑。
因为我们把它称为事务,这个“一致性”应该和数据库 acid 中的 C 是有类似的含义吧? |
31
22yune 2020-04-28 23:27:27 +08:00 via Android 2
我的理解就是#7 说的:最终一致性就是没有一致性。
首先,最终一致性是基于一致性概念衍生的。本来一致是一个原子的概念,一致=没有分歧,没有说部分一致的。 在分布式场景下,一致代价太大。基于 cap,为了 a,只能放弃 c,但业务场景又不能完全放弃。然后就想办法把 c 分级了,就是一致性模型。然后把一致 改名为强一致了。其它的一致性模型都是部分一致的(就是不一致)甚至完全没有一致性保证。其中“如果经过一段时间后要求能访问到更新后的数据,则是最终一致性”(引用自 http://www.blogjava.net/hello-yun/archive/2012/04/16/376744.html )。 一致性模型中,基于读写及它们的开始时间结束时间,及它们的进程关系这些要素来定义约束,命名一致性模型。非强一致性的模型都只能保证部分一致。无保证的场景就说是最终一致的(可以基于超时额外增加验证补偿机制)。 最终一致性只是部分一致性的一个美化的名字。把不一致说的好像是一致的。不知道是为了忽悠谁。 |
33
VishvaWang 2020-04-29 00:10:27 +08:00 via Android 2
两个要点
一致:保证不同节点之间的数据是相同的 最终:保证未来的某个时间是一致的,至于这个时间是多久,要看具体的协议,可能一分种之内,一小时之内,下一次数据写入之前,或者,下十次数据写入之前,或者我也不知道啥时候能一致,但是我的算法能保证最终是一致的,恩,最终,你懂了吧! |
34
coldear 2020-04-29 00:33:37 +08:00
先说一下我理解的一致性,就是每次写操作后的读操作都能返回最新的数据。
然后就是我理解的为什么会有最终一致性这个东西,其实就是一种妥协。 为了得到高可靠性,需要数据和服务不能只在一个节点。 此时,就产生了一个问题,数据读写的时候需要同步到所有节点,延迟就更高了。 但有些场景又不能忍受那么高的延迟,这时为了得到低延迟,不得不作出妥协,可以容忍写操作后一段时间内系统仍然返回老的数据。 至于怎么实现最终一致性,有各种各样的技术,这就是分布式系统主要讲的内容。 |
35
ericls 2020-04-29 03:59:35 +08:00
网游
假如每个人的位置是一行记录,每个玩家的客户端是一个副本 如果要强一致性,那只能一个人先走,等这个状态在所有玩家屏幕上反应出来的时候,下一个再走。 |
36
cassyfar 2020-04-29 05:11:22 +08:00 1
首先最终一致性里的 C,是指 CAP 里的 C,是 every read gets most recent write
其次最终一致性的 service 不遵循 ACID,大多数时候是遵循 BASE (basic availability, soft state, eventually consistency) 但是最终一致性是一致性,因为最终他一致了,这个还是非常关键的。选择使用最终一致性是一种妥协,不仅包含对于 A 和 P 的优先满足,也是因为写的次数远少于读,和每次写所需要传播的时间不长。 |
37
Aresxue 2020-04-29 11:31:29 +08:00 1
@EmdeBoas 我只是大概知道题主想问什么,所以说的比较简单。ACID 是事务的概念,但要区分的话主要是数据库事务以及业务层的事务,数据库事务的 C 是非常清晰的,业务层的事务建立在数据库事务之上,它的 C 就像你说的模糊,但一般情况下业务层事务很少谈到 ACID,ACID 默认情况下其实指的是数据库事务。CAP 的 C 指的就是多个副本数据的一致性, 你说的强一致性包括答主所说的最终一致性只是对数据同步延迟的不同要求, 强一致性适用于实时交易系统,最终一致性多用于离线计算系统, 而像 zk 这种半写集群的一致性要求强度在两者之间。
|
38
EmdeBoas 2020-04-29 13:47:38 +08:00 1
@Aresxue
1. ACID 这个概念已经被滥用,有各种解释,就像"一致性"这个词语被滥用一样,这也是造成现在大家认知混乱的原因;建议看看 DDIA 里面作者的观点,我看了是收益良多 2. 从你的回答可以看出你没有读过 CAP 的论文,也不清楚它真正的价值到底在哪里(提到 CAP 就只知道三选二的都是在网上碎片化获取的知识);关于 C 到底是什么含义:可以参考 https://www.the-paper-trail.org/page/cap-faq/ 3. 大家理解的所谓强一致:“写了就能读到最新的”,在工业实践上面是不可能做到的,在有各种延迟的情况下,数据“最新”就是一个不存在的说法; linearizably 就是工业实践能做到的最强一致性,zk 提供了 linearizably 的 sync 接口;你说的多数派叫 Quorum,问题的范畴属于我楼下提到的共识问题( Paxos 、Raft 、ZAB ( zk 使用的这个)都属于 quorum-based 的共识算法),你可以去了解一下 Quorum 和 2PC 的区别,是做了什么 trade-off,解决什么问题 什么场景来用;现在主流保证多个数据副本之间一致性用的算法也就是上面提到的 Quorum-based 的算法,对于 server 端自己来讲这是共识问题,一致性这个东西的主要观察对象是 client 端 |
39
sunriz 2020-04-30 22:12:49 +08:00
就是各节点同步有个过程呗,过程中,在不同节点读同个数据可能结果不同,但是这个同步过程完了就都一致了。
最终一致和强一致,说白了就是在所有节点都状态相同之前,允不允许在单个节点读到 |