你有没有遇到过这种情况?
你去银行取钱,排队的人很多。柜员告诉你:要么你先等(保证余额准确,但不一定能马上取到),要么你先拿走(能快速拿到,但余额可能不对)。
这其实就是分布式系统每天都要面对的选择题。
CAP理论是什么?
2000年,计算机科学家Eric Brewer提出一个猜想:一个分布式系统,不可能同时满足三个特性。
哪三个?
一致性(Consistency):所有节点看到的数据是一样的。你在A服务器写了数据,B服务器立刻也能读到。
可用性(Availability):每次请求都能得到响应。不管系统多忙,永远告诉你"行"或"不行"。
分区容错性(Partition Tolerance):网络出问题时系统还能继续工作。节点之间通信断了,不影响整体运行。
这三个听起来都很美好。但Brewer说:你最多只能同时满足两个。
这就好比鱼和熊掌不可兼得。
为什么不能同时满足?
打个比方。
想象两个仓库,A和B,库存数据要同步。正常情况下,A进了货,B也更新了。一切完美。
但某天网络断了,A和B之间连不上了。
这时候有人来B仓库提货。你怎么办?
选一致性:告诉客户"系统繁忙,请稍后再试"。B仓库的数据可能过时了,不敢乱发货。一致性保住了,但可用性没了。
选可用性:直接发货。B仓库数据可能不是最新的,但客户拿到了货。可用性保住了,但一致性没了。
网络分区(Partition)是分布式系统的常态,不是例外。网络抖动、光缆被挖断、机房断电……这些每天都在发生。
所以分区容错性(P)基本是必须选的。问题就变成:CP还是AP?
CP和AP,各适合什么场景?
CP(一致性+分区容错):数据对了,比什么都重要。
银行账户就是典型。你转账100块,绝不能因为网络问题导致两边都加了100。一致性必须保证。
关系型数据库(MySQL、PostgreSQL)大多是CP取向。分布式数据库(HBase、Cassandra的某些配置)也偏向CP。
特点:网络出问题时会拒绝部分请求,保证数据准确。
AP(可用性+分区容错):系统在线,比什么都重要。
社交媒体的点赞数、电商的商品浏览量。这些数据稍微有点延迟没关系,用户看到的就是"差不多对"的。
典型的AP系统:DynamoDB、Cassandra(默认配置)、DNS。
特点:网络出问题也继续响应,数据最终会一致。
现实中的取舍
好消息是:CAP不是绝对的。
很多系统采用"折中方案"。
比如,MySQL主从复制。主库写数据,从库异步同步。正常情况下读从库也能读到最新数据。网络分区时,从库可能延迟几秒。
这不是严格的CP,也不是纯AP,而是"最终一致性"。
Redis集群也是类似思路。某些场景下可以牺牲一点一致性,换取更高的可用性和性能。
云服务商也提供了很多配置选项。你可以自己决定:在这个服务上,我更想要CP还是AP。
总结一下
CAP理论告诉开发者一件事:分布式系统没有银弹。
你要根据业务场景做选择:
- 银行转账、支付系统 → CP,数据不能出错
- 社交动态、视频播放量 → AP,先让用户用上再说
- 大多数系统 → 最终一致性,折中方案
理解CAP不是要背概念,而是遇到问题时知道往哪个方向思考。
下次看到"系统维护中"或"数据可能延迟",你就知道:这是工程师们在CAP之间做的权衡。
你的业务,更偏向CP还是AP?