分布式系统设计陷阱,白话CAP理论
一、CAP
是啥?—— 三个不能全要的"超能力"
想象你开了一家连锁超市(分布式系统),有 3 个超能力供选择:
一致性(Consistency)
:所有分店货架商品实时同步,顾客在任何分店看到的商品价格/库存完全一致可用性(Availability)
:24 小时营业,顾客随时来都能买到东西(哪怕货架可能没及时补货)分区容错(Partition Tolerance)
:某分店断网断电也不影响其他分店营业(抗风险能力)
二、三种组合怎么选?—— 不同场景的生存法则
1. CP 组合
(银行系统首选)
选择:一致性 + 分区容错
代价:可能暂时停业(牺牲可用性)
场景:
- 银行转账:宁可暂停服务也要保证转账金额绝对准确
- 医疗系统:病人用药记录必须全院一致,哪怕部分科室断网也要先停服务
问题:
- 网络故障时用户可能看到"系统维护中"提示
- 恢复时间取决于网络修复速度
2. AP 组合
(互联网应用主流)
选择:可用性 + 分区容错
代价:数据可能短暂不一致
场景:
- 朋友圈点赞:先让你看到点赞动画,后台慢慢同步数据
- 电商秒杀:显示"抢购成功"但实际可能超卖,后续再处理退款
问题:
- 可能出现"幽灵商品"——你刚买的商品在别人手机显示已售罄
- 需要额外机制最终同步数据
3. CA 组合(几乎不存在)
选择:一致性 + 可用性
代价:放弃分区容错 → 本质是单机系统
场景:
- 小型单店超市:没有分店,自然不需要考虑分店同步问题
- 本地文件存储:只在一台电脑保存文件
问题:
- 一旦断网整个系统崩溃
- 无法扩展成大型系统
三、为什么必须放弃一个?—— 用快递站理解矛盾
假设你在两个小区各开一个快递站(分布式节点):
- 要一致性:每次有新快递,必须等两个站点都更新完数据才能营业 → 可能延迟开门(牺牲可用性)
- 要可用性:来快递先放自己站点就营业,另一个站点数据可能不同步 → 用户可能跑错站点取件(牺牲一致性)
- 要抗风险:必须允许某个站点临时关门(否则无法应对停电等意外)
这就是 CAP 的经典困境
四、BASE
:给AP组合的"后悔药"
BASE理论是对CAP中一致性和可用性权衡的结果, BASE理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。
1. 三颗救命丸
基本可用 (Basically Available)
:像双十一把图片质量调低,先保住不崩溃软状态 (Soft state)
:允许订单显示"配送中"而不是精确到米最终一致 (Eventually consistent)
:像跨行转账夜间批量处理
2. 经典补救案例
- 微信消息状态:先显示发送成功,再同步已读状态
- 机票超卖:先出票再协调退改签
五、实际工程中的生存指南
1. 优先保命原则
- 金融/医疗系统 → 选 CP(命比体验重要)
- 社交/电商系统 → 选 AP(体验比绝对准确重要)
2. 动态调整技巧
- 柔性事务:像淘宝下单,先扣库存再慢慢同步支付状态
- 降级策略:双十一把某些功能从 CP 降级为 AP,先扛住流量
3. 常见坑点
- 误把 CA 当分布式:用 MySQL 主从复制却要求强一致,结果主库宕机全挂
- 过度追求 AP:转账系统用 AP 模型导致重复打款
“设计分布式系统就像谈恋爱,总要有所妥协。要么放弃随时秒回(A),要么接受偶尔说谎(C),但绝不能不接电话(P)” —— 来自某大厂架构师的深夜朋友圈