CAP 理论概述
在分布式系统中,系统面临三大核心问题:
- 一致性(Consistency):所有节点的数据始终保持一致。
- 可用性(Availability):系统始终能够响应请求,无论请求是否成功。
- 分区容错性(Partition Tolerance):系统能够在部分机器故障、网络故障、机房停电等异常情况下继续运行。
CAP 定理的核心内容是,在一个分布式系统中,分区容错性(P) 和 一致性(C)、可用性(A) 三者之间是相互制约的。也就是说,如果发生网络分区,系统只能选择保证 一致性 或 可用性,但不能同时保证这两者。
理解 CAP 理论非常重要,可以让我们在职场上,当领导给出的任务不靠谱时,我们可以依据 CAP 去否决它。
比如,有这么一个任务,给你定了三大目标:
- 既要提升系统的可用性
- 又要保证数据的实时可见
- 还有提升系统的容错能力
完成这个任务是不可能的(至少在现有的硬件体系和软件架构的场景下是不可能的)。但是,如果你不理解 CAP,保证完成任务,那么职场是不需要眼泪和后悔的。
CAP 本身基于状态,基于瞬态,是一个描述性的理论,它并不解决工程问题。本质是在告诉大家,在分布式系统里,需要妥协。
分布式的存储系统会有很多的节点,这些节点都是通过网络进行通信。而网络是不可靠的,当节点和节点之间的通信出现了问题,此时,就称当前的分布式存储系统出现了分区。但是,值得一提的是,分区并不一定是由网络故障引起的,也可能是因为机器故障。
分布式存储系统要求能够自动容错,也就是说,分区可容忍性总是/必须要满足的,因为只有满足了P,才有实现C和A的基础,因此,一致性和写操作的可用性不能同时满足(是指发生了网络分区的时候才无法保证,没有网络分区时是可以保证CA同时发生的,所以说CAP是基于瞬态的。)。
但是要理解,机器故障、网络故障、机房停电等异常情况不是一直出现的,是一种概率相对较低,但是从长远来看又一定会发生的事件。当出现了网络分区就需要我们做出抉择,是保证C还是保证A
这是现在所有分布式框架设计的理论基础。
下面开始正题
1. 什么是分区容错性(Partition Tolerance)?
分区容错性(Partition Tolerance,简称 P)是 CAP 定理 中的一个重要特性。它指的是,在分布式系统中,即使网络发生了故障或者出现了节点之间无法通信的情况,系统仍然能够继续运行,而不会崩溃或失效。P 是在分布式系统中处理网络分区或通信故障的能力。
在网络发生分区时,系统的一部分可能和其他部分无法通信。为了避免整个系统崩溃,系统必须能够保持其运行,即使其中一部分处于无法访问的状态。
2. 为什么分区容错性重要?
在分布式系统中,多个计算机(或节点)分布在不同的物理位置,它们之间需要通过网络进行通信和数据交换。网络是一个可能发生故障的地方,故障可能由多种原因引起,例如:
- 网络硬件故障
- 路由器问题
- 网络连接不稳定
- 服务器故障
当这些故障发生时,可能会导致一部分节点和其他节点之间失去连接,这就是所谓的 网络分区。如果系统没有分区容错性,那么一旦网络分区发生,系统可能会完全崩溃或者变得不可用。
为了确保系统的可靠性和持续运行,分区容错性就显得至关重要。它可以保证即使部分系统节点无法通信,其他节点仍然能够继续工作。
3. 发生场景:什么情况下会发生网络分区?
分区容错性只在发生 网络分区 时起作用。网络分区的场景可以是以下几种:
- 物理网络故障:某些数据中心的网络设备或链路发生故障,导致节点间无法通信。
- 服务器故障:某个服务器或者一组服务器发生故障,无法与其他节点连接。
- 网络延迟过高:由于节点之间距离过远或者网络拥堵,导致请求的延迟非常高,导致节点无法及时收到其他节点的响应。
- 路由错误:路由器发生故障,导致消息无法传递到目标节点。
这些情况都会导致网络分区的发生,系统的一部分可能变得不可访问,而其他部分仍然可以工作。
4. 如何做到分区容错性(P)?
当网络分区发生时,分布式系统必须决定如何继续提供服务。通常有两个主要的选择:
- 继续提供服务,保证可用性(AP)。
- 暂停部分服务,保证一致性(CP)。
分区容错性要求系统在网络分区的情况下,能够选择其中之一,而不会完全停止工作。
步骤 1:检测网络分区
每个节点都有机制来检测与其他节点的连接是否正常。常见的方法是 心跳机制,即节点定期向其他节点发送信号(“心跳”),以确认是否能正常通信。
- 如果一个节点长时间没有收到其他节点的心跳信号,它就会认为自己和其他节点之间的网络连接可能已经发生问题,这就是 网络分区。
- 在发生分区时,节点可以根据检测到的网络状态,决定自己如何行动。
步骤 2:选择操作策略
在网络分区的情况下,系统必须选择一种策略:继续提供服务(可用性优先),或者暂停部分操作(一致性优先)。具体选择哪种策略,取决于系统的设计和业务需求。
-
选择可用性(AP):即使数据不一致,系统仍然会继续响应请求。这意味着系统的某一部分可能与其他部分不同步,但是不会停止服务。例如,用户在某一节点更新了数据,其他节点可能还没有收到更新,但用户仍然可以继续操作。这是现在大部分高并发的系统选择的方案,例如熟知的京东,PDD,淘宝等。但是不代表不考虑CP,追求的是最终一致性。
-
选择一致性(CP):在发生网络分区时,系统可能会暂停某些操作,直到确保所有数据一致(在超大数据量的场景下代价很高)。这种方式保证了数据在所有节点之间的一致性,但可能会导致部分服务不可用。
步骤 3:解决数据冲突(如果选择了可用性)
当系统选择保证 可用性(AP) 时,不同的分区节点可能会对同一数据进行不同的修改,导致数据冲突。在这种情况下,系统需要通过一些机制来解决数据冲突。
- 冲突解决策略:可以通过时间戳、版本号或者其他规则来决定哪个数据版本是“正确”的。
- 最后写入胜(Last Write Wins):选择时间戳更新更晚的数据版本。
- 手动解决冲突:通过管理员或者应用层逻辑来合并或选择合适的数据版本。
步骤 4:数据同步(如果选择了一致性)
如果系统选择了 一致性(CP),那么当网络分区恢复时,系统会执行数据同步过程,将分区前后不一致的数据进行同步,确保数据一致性。
- 一致性协议:比如 Paxos 或 Raft,这些协议可以帮助系统确保在网络恢复时,各个节点的数据是同步的。
- 同步数据:数据同步可能会导致延迟,系统会通过写入日志、复制数据等方式,确保数据的一致性。
步骤 5:恢复并继续操作
当网络分区恢复时,系统会重新连接失去连接的节点,并进行数据同步。根据之前的选择策略,系统将恢复操作:
- 如果选择了可用性,系统会确保服务不中断,尽管数据可能不一致,系统会继续提供服务并解决冲突。
- 如果选择了一致性,系统会暂停服务直到数据同步完成,确保数据的一致性。
5. 具体实例:Redis (AP)与 HBase(CP)
- Redis 是一个典型的 AP 系统,它在发生网络分区时,仍然会继续响应请求,允许数据在不同节点上不一致,分区恢复后会同步数据并解决冲突。
- HBase 是一个典型的 CP 系统,它会在发生网络分区时暂停部分操作,直到系统确保所有节点的数据一致性。网络恢复后,系统会同步数据,确保一致性。
6. 总结
分区容错性(P) 是指在网络分区发生时,分布式系统能够继续运行的能力。它确保即使系统的部分节点无法通信,系统的其他部分也能继续提供服务。系统必须根据实际情况做出选择:
- 可用性(AP):系统继续响应请求,可能导致数据不一致。
- 一致性(CP):系统暂停服务,直到确保数据一致性。
在设计分布式系统时,理解 分区容错性 是至关重要的,因为网络分区是不可避免的,必须采取合适的策略来保证系统的高可用性和稳定性。