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做分布式锁,结果数据不一致出了大问题。选型之前,先想清楚你的业务到底需要什么。

好,这一章就到这里。下一章,咱们聊聊注册中心的核心数据模型,看看服务实例到底是怎么存储的。