3、CAP理论与注册中心:CAP理论详解、AP与CP的选择
好,咱们进入第三章。这一章,我打算把CAP理论彻底讲透。
说实话,我见过太多人把CAP背得滚瓜烂熟,但一到实际选型就懵了。为什么ZooKeeper是CP?为什么Eureka是AP?很多人只记住了结论,没搞懂背后的逻辑。
今天,咱们就从根上把它理清楚。
3.1 CAP理论:到底在说什么?
CAP理论是分布式系统的基石。它由Eric Brewer在2000年提出,说白了就是一句话:
一个分布式系统,最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)中的两个。
嗯,这里要注意,不是三个都能选,而是三选二。
CAP三要素详解:
- C(Consistency)一致性:所有节点在同一时刻看到的数据是一样的。你写入了A节点,读B节点时,必须读到最新的数据。
- A(Availability)可用性:每个请求都能得到一个非错误的响应,但不保证是最新的数据。说白了,系统还能用,别挂。
- P(Partition Tolerance)分区容错性:系统内节点之间网络断了,系统还能继续工作。这在分布式系统里是必须的,因为网络一定会出问题。
我个人习惯把CAP理解成一个不可能三角。你想想看,网络分区是常态,所以P是必选的。那剩下的,就是在C和A之间做取舍。
我的经验:我在项目中遇到过好几次,团队争论到底选CP还是AP。其实没有绝对的对错,关键看业务场景。比如支付系统,你肯定要C;但用户点赞,A更重要。
3.2 AP与CP的选择:到底怎么选?
好,既然P是必选的,那问题就变成了:你愿意牺牲一致性,还是牺牲可用性?
咱们来看两种场景:
| 场景 | 选择 | 原因 |
|---|---|---|
| 银行转账、库存扣减 | CP | 数据必须一致,宁可系统暂时不可用,也不能出现数据错误 |
| 用户点赞、日志收集 | AP | 可用性优先,数据最终一致就行,用户不能等 |
| 服务注册与发现 | AP(多数场景) | 注册中心挂了,服务还能用缓存数据继续运行 |
为什么会这样?我举个例子你就明白了。
假设你有三个节点,网络突然断了,节点A和节点B、C之间无法通信。
- 选CP:节点A会拒绝写入,保证数据一致。但代价是,节点A不可用了。
- 选AP:节点A继续接受写入,但数据可能和B、C不一致。等网络恢复后,再慢慢同步。
避坑指南:我曾经犯过一个错误,在一个高并发场景下选了CP,结果网络抖动时整个服务都不可用了。后来改成AP,虽然数据有短暂不一致,但系统稳定多了。记住,没有完美的方案,只有适合的方案。
3.3 为什么ZooKeeper是CP?
ZooKeeper,很多人叫它ZK。它本质上是一个分布式协调服务,不是专门做注册中心的。但很多人拿它当注册中心用。
ZK的核心是ZAB协议(ZooKeeper Atomic Broadcast)。这个协议保证了强一致性。
ZK的CP特性体现在哪里?
- Leader选举期间不可用:当Leader挂了,ZK会重新选举。选举期间,整个集群不对外提供服务。这就是牺牲了可用性,保证了数据一致性。
- 写操作必须经过Leader:所有写请求都要先到Leader,Leader同步给Follower,超过半数确认后才算成功。如果网络分区,少数派那边的节点会拒绝写入。
- 读操作可能读到旧数据:嗯,这里要注意,ZK的读操作不一定读到最新数据。但写操作是强一致的。
核心结论:ZK在发生网络分区时,会优先保证数据一致性,宁可让部分节点不可用。所以它是CP系统。
我记得有一次,线上ZK集群因为网络抖动触发了Leader选举,整个注册中心停了十几秒。那十几秒里,新服务无法注册,老服务无法心跳续约。虽然最后数据没丢,但那个体验确实不好。
3.4 为什么Eureka是AP?
Eureka是Netflix开源的注册中心,也是Spring Cloud早期的标配。它和ZK走了完全不同的路。
Eureka的AP特性体现在哪里?
- 自我保护机制:当Eureka Server检测到大量心跳丢失时,它不会立刻剔除服务。它会进入自我保护模式,保留所有注册信息。说白了,宁可保留可能已经挂了的服务,也不让系统不可用。
- 所有节点平等:Eureka没有Leader的概念。每个节点都是对等的,都可以接受读写请求。即使某个节点挂了,其他节点还能正常工作。
- 最终一致性:Eureka的节点之间通过异步复制数据。你写入A节点,B节点可能不会立刻看到。但过一会儿,数据就同步过去了。
我的经验:我曾在生产环境用Eureka部署了3个节点。有一次其中一个节点所在的机器宕机了,但另外两个节点完全不受影响,服务照样注册和发现。这就是AP的好处——系统不会因为单点故障而瘫痪。
你想想看,注册中心的核心职责是什么?是让服务能找到彼此。如果注册中心挂了,服务之间还能通过本地缓存继续通信。但如果注册中心为了强一致性而拒绝服务,那整个系统就真的挂了。
所以,Eureka选择了AP。它认为,可用性比一致性更重要。数据可以暂时不一致,但系统不能停。
3.5 总结:选ZK还是Eureka?
好,咱们来做个对比总结。
| 特性 | ZooKeeper(CP) | Eureka(AP) |
|---|---|---|
| 一致性 | 强一致性 | 最终一致性 |
| 可用性 | 选举期间不可用 | 始终可用 |
| 分区容忍性 | 牺牲少数派 | 保留所有节点 |
| Leader | 有Leader | 无Leader |
| 适用场景 | 配置管理、分布式锁 | 服务注册与发现 |
我个人建议:如果你做服务注册与发现,优先选AP的注册中心。比如Eureka、Nacos(AP模式)、Consul(AP模式)。
但如果你需要分布式锁、配置管理这些强一致性的场景,那ZK是更好的选择。
最后提醒一句:不要盲目跟风。我见过有人把ZK当注册中心用,结果每次网络抖动都提心吊胆。也见过有人用Eureka做分布式锁,结果数据不一致出了大问题。选型之前,先想清楚你的业务到底需要什么。
好,这一章就到这里。下一章,咱们聊聊注册中心的核心数据模型,看看服务实例到底是怎么存储的。