欢迎来到啾啾的博客🐱。
记录学习点滴。分享工作思考和实用技巧,偶尔也分享一些杂谈💬。
有很多很多不足的地方,欢迎评论交流,感谢您的阅读和评论😄。
目录
引言
总所周知,CAP定理指出,一个分布式无法同时满足以下三个特性,最多只能满足其中两个:
- 一致性 (Consistency - C):所有节点在同一时间具有相同的数据。任何读操作都能读到最新的写操作结果。
- 可用性 (Availability - A):每个请求(无论读写)都能收到一个(非错误的)响应,但不保证响应的数据是最新版本。
- 分区容错性 (Partition Tolerance - P):系统在遇到任何网络分区(即节点间的网络通信发生故障)时,仍然能够继续运行。
核心结论:在现代分布式系统中,网络故障是必然会发生的,所以 分区容错性P是一个必须满足的前提条件。因此,CAP 定理的实际抉择变成了:当网络分区发生时,你必须在一致性C和可用性A之间做出选择。
这样的CAP定理是有局限性的,其更像一个“故障发生时”的法则,告诉网络故障时怎么权衡。它没有告诉我们在系统整行运行时如何权衡。
而系统在99.99%的时间可能都是正常运行的。
The CAP theorem’s impact on modern distributed database system design is more limited than is often perceived. Another tradeoff—between consistency and latency—has had a more direct influence on several well-known DDBSs. A proposed new formulation, PACELC, unifies this tradeoff with CAP.
CAP 定理对现代分布式数据库系统设计的影响,实则不如人们通常所认为的那般大。另一种权衡 —— 即在一致性和延迟之间的权衡 —— 对若干知名分布式数据库系统(DDBSS)产生了更为直接的影响。一种新提出的表述 PACELC,将这种权衡与 CAP 统一起来 。
PACELC资料
-
论文
https://www.cs.umd.edu/~abadi/papers/abadi-pacelc.pdf -
博文
https://hazelcast.com/blog/navigating-consistency-in-distributed-systems-choosing-the-right-trade-offs/
PACELC定理:更完整的分布式视角
PACELC 的名字就是其内容的缩写,它是一个条件语句:
如果P发生网络分区,系统就必须在可用性A 和一致性C 之间做出权衡。否则 E,当系统正常运行时,它就必须在延迟 L和一致性 C之间做出权衡。
其中ELC是定理的精髓和创新之处。它指出了在系统没有网络故障的“和平时期”,存在一个全新的、同样重要的权衡:延迟 (Latency) 和一致性 C。
-
追求更高的一致性 C:
- 如何实现? 当一个写操作发生时,系统必须将这个更新同步到多个副本(或所有副本),并等待它们全部确认后,才能向客户端返回成功。
- 代价是什么? 这个等待同步和确认的过程需要时间,从而增加了延迟 (Latency)。用户会感觉系统响应变慢了。
-
追求更低的延迟 (L):
- 如何实现? 当一个写操作发生时,系统可能只写入主节点或本地节点,然后立即向客户端返回成功,再异步地将数据复制到其他副本。
- 代价是什么? 在数据尚未完全同步到所有副本的这段时间里,如果一个读请求打到了其他副本上,就会读到旧数据,从而牺牲了一致性 C(通常是“最终一致性”)。
PACELC 定理下的系统分类
根据 PACELC,我们可以将分布式系统分为四种主要类型,这比单纯用 CAP 来分类要精确得多。
PC/EC 系统 (高 C)
分区时选 C,平时也选 C。
这类系统在任何情况下都把数据一致性放在第一位。
- 例子:
传统的关系型数据库 (RDBMS),如 MySQL Cluster、PostgreSQL,通过 ACID 事务和两阶段提交等机制来保证强一致性,代价是可用性降低和延迟增高。
Google Spanner/Megastore, VoltDB:这些是专为强一致性设计的分布式数据库。
PA/LC 系统 (高 A, 低 L)
分区时选 A,平时选 L。
这类系统在任何情况下都优先保证高可用和低延迟的体验。
- 例子:
Amazon DynamoDB, Apache Cassandra: 它们是 “Eventually Consistent” (最终一致) 系统的典型代表。写操作会快速返回,数据异步复制。它们容忍数据在短时间内不一致,以换取极高的可用性和极低的响应延迟。
Riak: 另一个类似 Dynamo 设计的数据库。
PC/LC 系统 (混合型)
分区时选 C,平时选 L。
这类系统在设计上很有趣。它们希望在正常情况下有较低的延迟(接受最终一致性),但在出现故障时,又能保证数据不会错乱。
- 例子:
MongoDB: 在默认配置下,写操作只发生在主节点上,保证了强一致性。但在分区发生时,系统会进行主节点选举,保证新的主节点在多数派分区中,从而选择了C。然而,MongoDB 允许“读偏好”(Read Preference)设置为从从节点读取,这样可以降低读延迟(L),但会牺牲一致性(C)。所以它可以被配置为 PC/LC 模式。
PA/EC 系统 (混合型)
分区时选 A,平时选 C。
这种组合比较少见,因为它意味着系统在正常运行时愿意为强一致性付出高延迟的代价,但在发生故障时,却又愿意放弃一致性来保证可用性。逻辑上有些矛盾,所以现实中很少有系统被设计成这样。
总结
定理 | 关注点 | 核心权衡 | 适用场景 |
---|---|---|---|
CAP | 系统故障时 | 在网络分区P的前提下,可用性 A vs 一致性 C | 宏观的、理论性的系统设计指导 |
PACELC | 故障时 + 正常时 | 1. 故障时: A vs C 2. 正常时: 延迟 L vs 一致性C | 更具体、更实用的系统选型和架构决策框架 |
PACELC 定理告诉我们,延迟和一致性的权衡 (L vs C) 是我们在日常系统设计和优化中每天都要面对的问题,而 CAP 提到的权衡 (A vs C) 则是在异常情况下的底线策略。
当你为你的业务选择一个数据库或消息队列时,使用 PACELC 模型来分析它的特性会非常有帮助:
- 这个系统在网络不好的时候会怎么样?(PA or PC)
- 这个系统在平时为了保证数据同步,响应速度会慢吗?(EC or LC)
通过回答这两个问题,你就能更准确地判断这个系统是否符合你的业务需求。