对于从事分布式系统开发或设计的架构师和工程师而言,CAP 理论是必须掌握的基础知识。CAP 理论能够帮助他们在系统设计中做出目标取舍,合理规划系统拆分的维度。下面先来探讨分布式系统的特点。
一、分布式系统的特点
随着移动互联网的迅猛发展,互联网用户数量不断攀升,所产生的数据规模也日益庞大,这对应用系统提出了更高要求。我们的系统必须能够支持高并发访问和海量数据处理。
分布式系统通常是建立在网络之上的硬件或软件系统,彼此之间通过消息等方式进行通信和协调。其核心在于可扩展性,通过对服务和存储进行扩展,提升系统的处理能力,使多台服务器协同工作,以完成单台服务器无法处理的任务,尤其是高并发或大数据量的任务。
除了可扩展性需求,分布式系统还具有不出现单点故障、服务或存储无状态等特点。单点故障是指系统中某个组件一旦失效,会导致整个系统无法工作。而分布式系统的设计目标之一就是避免单点故障,确保单点问题不影响整体。无状态则是因为无状态的服务能够满足部分机器宕机不影响全部的需求,并且可以随时进行扩展。
由于分布式系统的这些特点,在分布式环境中更容易出现问题,如节点之间通信失败、网络分区故障、多个副本的数据不一致等。为了更好地在分布式系统下进行开发,学者们提出了一系列理论,其中具有代表性的当属 CAP 理论。
二、CAP 代表的含义
CAP 理论可以表述为:一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容忍性(Partition Tolerance)这三项中的两项。
一致性是指“所有节点同时看到相同的数据”,即更新操作成功并返回客户端完成后,所有节点在同一时间的数据完全一致,等同于所有节点拥有数据的最新版本。
可用性是指“任何时候,读写都是成功的”,即服务一直可用,且响应时间正常。我们平时会看到一些 IT 公司的对外宣传,比如系统稳定性已经做到 3 个 9、4 个 9,即 99.9%、99.99%,这里的 N 个 9 就是对可用性的一种描述,称为 SLA(服务水平协议)。例如,月度 99.95%的 SLA 意味着每个月服务出现故障的时间只能占总时间的 0.05%,如果这个月是 30 天,那么就是 21.6 分钟。
分区容忍性具体是指“当部分节点出现消息丢失或者分区故障的时候,分布式系统仍然能够继续运行”,即系统容忍网络出现分区,并且在遇到某节点或网络分区之间网络不可达的情况下,仍然能够对外提供满足一致性和可用性的服务。
在分布式系统中,由于系统各层的拆分,P 是确定的,CAP 的应用模型就是 CP 架构和 AP 架构。分布式系统所关注的,就是在 Partition Tolerance 的前提下,如何实现更好的 A 和更稳定的 C。
三、CAP 理论的证明
CAP 理论的证明方式有多种,通过反证法最为直观。最早由 Lynch 提出用反证法来证明 CAP 定理。通过一个实际场景,如果 CAP 三者可同时满足,由于允许 P 的存在,则一定存在服务器之间的丢包,如此便不能保证 C。
首先构建一个单机系统,如图所示,Client A 可以发送指令到 Server 并且设置更新 X 的值,Client 1 从 Server 读取该值。在单点情况下,即没有网络分区的情况下,通过简单的事务机制,可以保证 Client 1 读到的始终是最新值,不存在一致性问题。
当我们在系统中增加一组节点时,由于允许分区容错,Write 操作可能在 Server 1 上成功,而在 Server 2 上失败。此时对于 Client 1 和 Client 2 来说,就会读取到不一致的值,出现不一致的情况。如果要保持 X 值的一致性,Write 操作必须同时失败,这就降低了系统的可用性。
由此可见,在分布式系统中,无法同时满足 CAP 定律中的“一致性”“可用性”和“分区容错性”三者。
在该证明中,对 CAP 的定义进行了更明确的声明:
- Consistency(一致性)被称为原子对象,任何的读写都应该看起来是“原子”的,或串行的,写后面的读一定能读到前面写的内容,所有的读写请求都好像被全局排序。
- Availability(可用性)对任何非失败节点都应该在有限时间内给出请求的回应(请求的可终止性)。
- Partition Tolerance(分区容忍性)允许节点之间丢失任意多的消息,当网络分区发生时,节点之间的消息可能会完全丢失。
四、CAP 理论的应用
CAP 理论提醒我们,在架构设计中,不要把精力浪费在设计能满足三者的完美分布式系统上,而要进行合理取舍。CAP 理论类似数学上的不可能三角,只能三者选其二,不能全部获得。
不同业务对一致性的要求各不相同。例如,在微博上发表评论和点赞,用户对不一致并不敏感,可以容忍相对较长时间的不一致,只要做好本地交互,就不会影响用户体验;而在电商购物时,产品价格数据则要求强一致性,如果商家更改价格不能实时生效,会对交易成功率产生极大影响。
需要注意的是,CAP 理论中忽略了网络延迟,即当事务提交时,节点间的数据复制一定需要花费时间。即使是在同一个机房,从节点 A 复制到节点 B,由于现实中网络不是实时的,所以总会存在一定的时间不一致。
五、CP 和 AP 架构的取舍
在通常的分布式系统中,为了保证数据的高可用,通常会保留数据的多个副本(Replica)。网络分区是既成的现实,因此只能在可用性和一致性之间做出选择。CAP 理论关注的是在绝对情况下,而在工程上,可用性和一致性并非完全对立。我们往往关注的是如何在保持相对一致性的前提下,提高系统的可用性。
业务上对一致性的要求会直接反映在系统设计中,典型的就是 CP 和 AP 结构。
-
CP 架构:对于 CP 来说,放弃可用性,追求一致性和分区容错性。我们熟悉的 ZooKeeper 就采用了 CP 一致性。ZooKeeper 是一个分布式的服务框架,主要用于解决分布式集群中应用系统的协调和一致性问题。其核心算法是 Zab,所有设计都是为了一致性。在 CAP 模型中,ZooKeeper 是 CP,这意味着面对网络分区时,为了保持一致性,它是不可用的。关于 Zab 协议,将在后面的 ZooKeeper 课程中介绍。
-
AP 架构:对于 AP 来说,放弃强一致性,追求分区容错性和可用性,这是很多分布式系统设计时的选择,后面的 Base 也是基于 AP 进行扩展的。与 ZooKeeper 相对的是 Eureka,Eureka 是 Spring Cloud 微服务技术栈中的服务发现组件。Eureka 的各个节点都是平等的,几个节点挂掉不影响正常节点的工作,剩余的节点依然可以提供注册和查询服务。只要有一台 Eureka 还在,就能保证注册服务可用,只不过查到的信息可能不是最新版本,不保证一致性。
文章(专栏)将持续更新,欢迎关注公众号:服务端技术精选。欢迎点赞、关注、转发。
个人小工具程序上线啦,通过公众号(服务端技术精选)菜单【个人工具】即可体验,欢迎大家体验后提出优化意见!