📋 Research Summary
研究发现CAP定理在2024-2025年的工程实践中已从"三选二"的简单理解演进为更细粒度的权衡模型。核心洞察:P(分区容错性)在分布式系统中是必须的,真正的选择是C与A的权衡;但更重要的是PACELC定理的提出——在没有分区时,系统需要在延迟(L)和一致性©之间做选择。工程实践表明,大多数现代数据库(如Cassandra、MongoDB)采用"最终一致性"模型,通过Quorum机制(N/2+1)在一致性和延迟之间找到平衡点。
🌱 逻辑原点
如果网络分区不可避免,我们究竟该牺牲一致性还是可用性?
当你发现:你的分布式系统在"双11"高峰期出现网络抖动——这时你面临选择:是返回可能过期的数据保证服务可用(A),还是拒绝请求等待数据同步(C)?问题是:你的业务场景能容忍"读到脏数据"吗?
🧠 苏格拉底式对话
1️⃣ 现状:最原始的解法是什么?
CAP定理:分布式系统的"不可能三角"
Eric Brewer在2000年提出,一个分布式系统最多只能同时满足以下三个特性中的两项:
class CAPTheorem:
"""
C = Consistency (一致性)
所有节点在同一时间看到相同的数据
A = Availability (可用性)
每个请求都能得到响应(成功或失败)
P = Partition Tolerance (分区容错性)
系统在网络分区时仍能继续运行
"""
def distributed_system_trilemma(self):
"""
理论上:8种组合,实际只有3种可行
"""
return {
"CA": "单机系统(无分区)",
"CP": "HBase, MongoDB, Redis",
"AP": "Cassandra, DynamoDB, CouchDB",
"PA": "同AP",
"AC": "同CA",
"PA": "同AP",
"APC": "❌ 不可能",
"None": "❌ 无意义"
}
三个特性的严格定义:
C – 一致性 (强一致性)
写操作完成后,任何后续读取都能获得最新写入的值
类似:单机数据库的ACID特性
A – 可用性 (高可用)
每个请求都必须得到响应(成功或失败)
但不保证响应的数据是最新的
P – 分区容错性
系统任意数量的消息丢失或失败时,仍能继续运行
在分布式系统中:网络分区是必然发生的
2️⃣ 瓶颈:规模扩大100倍时会在哪里崩溃?
场景:电商系统的库存扣减
传统CA系统的崩溃点:
用户A (北京) 数据库主库 (北京) 数据库从库 (上海)
| | |
|–写入: 库存=99 ———–>| |
| |—- 同步中 ——————–>|
| | |
|<— 返回成功 ————–| |
| | |
用户B (上海) |
| | |
|—- 查询库存 ————->|—- 网络分区!❌ —————|
| | |
网络故障!从库无法同步 |
| | |
|<— 返回库存=100(旧数据) —|—- 读到旧数据 ✅ |
| | |
结果:超卖!库存显示100,实际只有99 💥
CP系统的代价:
网络分区发生时:
CP系统(如HBase):
客户端:"我要查询库存"
节点B:"无法与主库通信,拒绝服务"
客户端:❌ 收到错误:"Service Unavailable"
代价:用户体验下降,但保证数据一致
AP系统(如Cassandra):
客户端:"我要查询库存"
节点B:"主库失联,返回本地数据(可能是旧的)"
客户端:✅ 收到响应(但可能过期)
代价:数据短暂不一致,但服务持续可用
规模扩大100倍的崩溃:
- 从单机房 → 跨地域多机房(网络分区概率大幅增加)
- 从千级并发 → 百万级并发(一致性协议开销爆炸)
- 从强同步 → 最终一致性(用户需要接受"读到旧数据")
3️⃣ 突破:必须引入什么新维度?
PACELC定理:CAP的扩展版
在分布式系统中:
P (Partition) 分区发生时
→ A (Availability) 可用性 vs C (Consistency) 一致性
E (Else) 无分区时
→ L (Latency) 延迟 vs C (Consistency) 一致性
工程实践:Quorum机制(NWR协议)
class QuorumConsistency:
"""
通过调整读写副本数,在不同场景下获得不同的一致性级别
"""
def __init__(self, N=3):
self.N = N # 总副本数
self.W = None # 写操作需要的成功副本数
self.R = None # 读操作需要的成功副本数
def strong_consistency(self):
"""
强一致性:W + R > N
读写集合必有交集,一定能读到最新数据
代价:更高延迟
"""
self.W = 2
self.R = 2
# W + R = 4 > N(3) = 强一致性
def eventual_consistency(self):
"""
最终一致性:W + R <= N
读写集合可能无交集,可能读到旧数据
好处:更低延迟,更高可用性
"""
self.W = 1
self.R = 1
# W + R = 2 <= N(3) = 最终一致性
def optimize_for_write(self):
"""
写优化:W=1, R=N
写入只要任意1个副本成功(低延迟)
读取需要所有副本响应(保证读到最新)
适合:写多读少场景
"""
self.W = 1
self.R = self.N
def optimize_for_read(self):
"""
读优化:W=N, R=1
写入需要所有副本成功(高延迟)
读取只要任意1个副本响应(低延迟)
适合:读多写少场景
"""
self.W = self.N
self.R = 1
实际案例:Cassandra的配置权衡
# Cassandra一致性级别配置
consistency_levels = {
"ALL": "所有副本都响应(CP:强一致,低可用)",
"QUORUM": "多数副本响应 (N/2 + 1)(平衡点)",
"LOCAL_QUORUM": "本地数据中心多数副本响应",
"ONE": "任意一个副本响应(AP:最终一致,高可用)",
"LOCAL_ONE": "本地数据中心任意副本响应"
}
# 3副本集群的QUORUM计算
N = 3
QUORUM = (N // 2) + 1 # = 2
# 写+读 = QUORUM + QUORUM = 4 > N(3)
# → 强一致性保证
📊 视觉骨架
#mermaid-svg-kjsOHJhIaj10FXtG{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-kjsOHJhIaj10FXtG .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kjsOHJhIaj10FXtG .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kjsOHJhIaj10FXtG .error-icon{fill:#552222;}#mermaid-svg-kjsOHJhIaj10FXtG .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kjsOHJhIaj10FXtG .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kjsOHJhIaj10FXtG .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kjsOHJhIaj10FXtG .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kjsOHJhIaj10FXtG .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kjsOHJhIaj10FXtG .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kjsOHJhIaj10FXtG .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kjsOHJhIaj10FXtG .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kjsOHJhIaj10FXtG .marker.cross{stroke:#333333;}#mermaid-svg-kjsOHJhIaj10FXtG svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kjsOHJhIaj10FXtG p{margin:0;}#mermaid-svg-kjsOHJhIaj10FXtG .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-kjsOHJhIaj10FXtG .cluster-label text{fill:#333;}#mermaid-svg-kjsOHJhIaj10FXtG .cluster-label span{color:#333;}#mermaid-svg-kjsOHJhIaj10FXtG .cluster-label span p{background-color:transparent;}#mermaid-svg-kjsOHJhIaj10FXtG .label text,#mermaid-svg-kjsOHJhIaj10FXtG span{fill:#333;color:#333;}#mermaid-svg-kjsOHJhIaj10FXtG .node rect,#mermaid-svg-kjsOHJhIaj10FXtG .node circle,#mermaid-svg-kjsOHJhIaj10FXtG .node ellipse,#mermaid-svg-kjsOHJhIaj10FXtG .node polygon,#mermaid-svg-kjsOHJhIaj10FXtG .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-kjsOHJhIaj10FXtG .rough-node .label text,#mermaid-svg-kjsOHJhIaj10FXtG .node .label text,#mermaid-svg-kjsOHJhIaj10FXtG .image-shape .label,#mermaid-svg-kjsOHJhIaj10FXtG .icon-shape .label{text-anchor:middle;}#mermaid-svg-kjsOHJhIaj10FXtG .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-kjsOHJhIaj10FXtG .rough-node .label,#mermaid-svg-kjsOHJhIaj10FXtG .node .label,#mermaid-svg-kjsOHJhIaj10FXtG .image-shape .label,#mermaid-svg-kjsOHJhIaj10FXtG .icon-shape .label{text-align:center;}#mermaid-svg-kjsOHJhIaj10FXtG .node.clickable{cursor:pointer;}#mermaid-svg-kjsOHJhIaj10FXtG .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-kjsOHJhIaj10FXtG .arrowheadPath{fill:#333333;}#mermaid-svg-kjsOHJhIaj10FXtG .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-kjsOHJhIaj10FXtG .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-kjsOHJhIaj10FXtG .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kjsOHJhIaj10FXtG .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-kjsOHJhIaj10FXtG .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kjsOHJhIaj10FXtG .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-kjsOHJhIaj10FXtG .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-kjsOHJhIaj10FXtG .cluster text{fill:#333;}#mermaid-svg-kjsOHJhIaj10FXtG .cluster span{color:#333;}#mermaid-svg-kjsOHJhIaj10FXtG div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-kjsOHJhIaj10FXtG .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-kjsOHJhIaj10FXtG rect.text{fill:none;stroke-width:0;}#mermaid-svg-kjsOHJhIaj10FXtG .icon-shape,#mermaid-svg-kjsOHJhIaj10FXtG .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kjsOHJhIaj10FXtG .icon-shape p,#mermaid-svg-kjsOHJhIaj10FXtG .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-kjsOHJhIaj10FXtG .icon-shape rect,#mermaid-svg-kjsOHJhIaj10FXtG .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kjsOHJhIaj10FXtG .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-kjsOHJhIaj10FXtG .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-kjsOHJhIaj10FXtG :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
实际可行的组合
CAP定理三要素
只能选2个
只能选2个
必须包含
一致性 C所有节点看到相同数据
可用性 A每个请求都有响应
分区容错性 P网络故障时仍能运行
CA系统单机数据库无分区
CP系统HBase/MongoDB牺牲可用性
AP系统Cassandra/DynamoDB牺牲一致性
网络层
节点B (从)
节点A (主)
客户端
网络层
节点B (从)
节点A (主)
客户端
#mermaid-svg-MWlcxnjR5KXO6N1S{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-MWlcxnjR5KXO6N1S .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-MWlcxnjR5KXO6N1S .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-MWlcxnjR5KXO6N1S .error-icon{fill:#552222;}#mermaid-svg-MWlcxnjR5KXO6N1S .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MWlcxnjR5KXO6N1S .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-MWlcxnjR5KXO6N1S .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MWlcxnjR5KXO6N1S .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MWlcxnjR5KXO6N1S .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-MWlcxnjR5KXO6N1S .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MWlcxnjR5KXO6N1S .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MWlcxnjR5KXO6N1S .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MWlcxnjR5KXO6N1S .marker.cross{stroke:#333333;}#mermaid-svg-MWlcxnjR5KXO6N1S svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MWlcxnjR5KXO6N1S p{margin:0;}#mermaid-svg-MWlcxnjR5KXO6N1S .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-MWlcxnjR5KXO6N1S text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-MWlcxnjR5KXO6N1S .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-MWlcxnjR5KXO6N1S .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-MWlcxnjR5KXO6N1S .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-MWlcxnjR5KXO6N1S .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-MWlcxnjR5KXO6N1S #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-MWlcxnjR5KXO6N1S .sequenceNumber{fill:white;}#mermaid-svg-MWlcxnjR5KXO6N1S #sequencenumber{fill:#333;}#mermaid-svg-MWlcxnjR5KXO6N1S #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-MWlcxnjR5KXO6N1S .messageText{fill:#333;stroke:none;}#mermaid-svg-MWlcxnjR5KXO6N1S .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-MWlcxnjR5KXO6N1S .labelText,#mermaid-svg-MWlcxnjR5KXO6N1S .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-MWlcxnjR5KXO6N1S .loopText,#mermaid-svg-MWlcxnjR5KXO6N1S .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-MWlcxnjR5KXO6N1S .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-MWlcxnjR5KXO6N1S .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-MWlcxnjR5KXO6N1S .noteText,#mermaid-svg-MWlcxnjR5KXO6N1S .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-MWlcxnjR5KXO6N1S .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-MWlcxnjR5KXO6N1S .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-MWlcxnjR5KXO6N1S .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-MWlcxnjR5KXO6N1S .actorPopupMenu{position:absolute;}#mermaid-svg-MWlcxnjR5KXO6N1S .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-MWlcxnjR5KXO6N1S .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-MWlcxnjR5KXO6N1S .actor-man circle,#mermaid-svg-MWlcxnjR5KXO6N1S line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-MWlcxnjR5KXO6N1S :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
场景1:CP系统(牺牲可用性)
场景2:AP系统(牺牲一致性)
场景3:PACELC权衡(无分区时)
alt
[强一致性(高延迟)-
]
[最终一致性(低延迟-
)]
写入数据 X=1
同步数据
网络分区!❌
读取数据
503 Service Unavailable
(拒绝服务,保证一致性)
写入数据 X=1
同步数据
网络分区!❌
读取数据
200 OK, X=0 (旧数据)
(服务可用,但数据不一致)
写入数据 X=1
同步数据 (跨机房)
等待所有副本确认…
确认写入
200 OK (延迟: 100ms)
200 OK (延迟: 5ms)
异步同步中…
关键对比:
| HBase | CP | 强一致性 | 金融系统、库存管理 |
| MongoDB | CP(可配置AP) | 可调一致性 | 文档存储、灵活模式 |
| Cassandra | AP | 最终一致性 | 大规模写入、日志系统 |
| Redis | CP/AP(取决于模式) | Sentinel:APCluster:CP | 缓存、会话存储 |
| Riak | AP | 最终一致性 | 高可用性要求场景 |
| CouchDB | AP | 最终一致性 | 离线优先应用 |
⚖️ 权衡模型
公式:
分布式系统设计 = 业务容忍度 × 技术选择 × 成本权衡
一致性模型的光谱:
强一致性 弱一致性
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Linearizable Causal Read Your Eventual
(可线性化) (因果一致性) Writes (最终一致性)
|
└─ 大多数NoSQL的平衡点
代价分析:
-
✅ 选择CP(一致性优先):
- 获得:数据绝对准确,无脏读
- 牺牲:部分故障时服务不可用
- 适用:金融交易、库存扣减、支付系统
-
✅ 选择AP(可用性优先):
- 获得:服务始终可访问,高吞吐
- 牺牲:短暂数据不一致,需要冲突解决机制
- 适用:社交动态、推荐系统、日志收集
-
⚠️ 工程实践的真相:
- PACELC定理揭示了CAP的局限性:
- 有分区时:A vs C
- 无分区时:L vs C(延迟 vs 一致性)
- 大多数系统不是纯粹CP或AP:
- 通过Quorum机制在两者间滑动
- 根据操作类型动态选择一致性级别
- PACELC定理揭示了CAP的局限性:
决策树:
你的系统能容忍短暂的数据不一致吗?
│
├─ 是 → 选择AP或配置为最终一致性
│ │
│ ├─ 需要支持多地域部署?
│ │ ├─ 是 → Cassandra (Masterless架构)
│ │ └─ 否 → MongoDB (可配置为AP)
│ │
│ └─ 写入量远大于读取量?
│ ├─ 是 → DynamoDB (写优化)
│ └─ 否 → CouchDB (读优化)
│
└─ 否 → 选择CP或配置为强一致性
│
├─ 需要复杂查询能力?
│ ├─ 是 → MongoDB (CP模式)
│ └─ 否 → HBase (列族存储)
│
└─ 对延迟极其敏感?
├─ 是 → Redis (内存数据库)
└─ 否 → 传统关系数据库 + 分库分表
工程实践建议:
不要迷信"三选二":
- 实际分布式系统必须有P(分区容错)
- 真正的选择是CP vs AP
一致性级别应该是可配置的:
- 不同操作要求不同一致性
- 例如:支付操作强一致性,浏览历史弱一致性
监控你的权衡结果:
- 监控数据不一致的持续时间
- 监控服务不可用的频率和时长
- 根据业务SLA动态调整
🔁 记忆锚点
class CAPTheorem:
"""
CAP = 分布式系统的铁三角约束
本质:在不可靠网络上构建可靠系统的根本权衡
"""
def __init__(self):
self.consistency = "所有节点看到相同数据"
self.availability = "每个请求都有响应"
self.partition_tolerance = "网络故障时仍能运行"
def the_hard_truth(self):
"""
工程实践的真相:P是必须的,真正的选择是C vs A
"""
return {
"theory": "C + A + P = ❌ 不可能",
"reality": "P (必须) + (C vs A) = 工程选择"
}
def pacelc_extension(self):
"""
PACELC定理:CAP的现代化扩展
P (分区) → A vs C
E (无分区) → L vs C (延迟 vs 一致性)
"""
return """
CAP只考虑了分区场景,
PACELC考虑了正常情况下的延迟权衡
大多数系统的选择:
– 有分区时:牺牲一致性保证可用性
– 无分区时:牺牲一致性降低延迟
"""
# 本质:在一致性、可用性、延迟之间做三维权衡
tradeoff = """
分布式系统的设计艺术:
1. 理解业务对数据不一致的容忍度
2. 理解用户对服务不可用的容忍度
3. 理解系统对延迟的敏感度
4. 通过Quorum机制找到平衡点
5. 根据不同操作动态调整一致性级别
"""
一句话本质:CAP定理不是技术的"三选二"游戏,而是对分布式系统本质约束的揭示——在不可靠网络上构建可靠系统时,你必须在一致性、可用性、延迟之间做出基于业务场景的权衡,且这种权衡是动态的、可配置的、多维度的。
Sources
- Choosing Storage with CAP Theorem – Ascend Corp (Jan 17, 2025)
- Understanding The CAP Theorem – Bitsrc (Feb 11, 2024)
- CAP 定理再审视:从理论误区到工程实践
- CAP & BASE理论详解 – JavaGuide
- The CAP Theorem With Apache Cassandra® and MongoDB – Instaclustr (Aug 3, 2021)
- PACELC design principle – Wikipedia
- Beyond CAP: Unveiling the PACELC Theorem for Modern Systems – Dev.to (Mar 15, 2025)
- CAP, PACELC, ACID, BASE – Essential Concepts – ByteByteGo (Oct 10, 2024)
- Consistency Tradeoffs in Modern Distributed Database Systems – Daniel Abadi (UMD)




