什么是CAP模型?


一、什么是CAP模型?

CAP模型指的是在分布式系统中,不可能同时满足以下三个点(最多只能满足两个点):

  • 一致性(Consistency):访问分布式系统的每一个节点都能获得最新的数据
  • 可用性(Availability):每次请求都会收到响应,但不保证数据是最新的
  • 分区容错性(Partition tolerance):分区之间可能会丢失/延迟一些消息,但不影响系统正常运行

二、为什么CAP模型不能同时满足?如何证明?

在CAP模型中,只能满足CP、AP,不能满足CA,因为网络通信的不稳定性可能会导致分区容错(也就是说分区容错性是必然存在的,因此我们只能在一致性和可用性之间做选择)。

证明如下
假设有两个服务器N1和N2,N1有应用程序A和数据库DB0,N2有应用程序B和数据库DB0,他们之间的网络可以互通,相当于分布式系统的两个节点,我们来做分析:

  • 在满足C的时候,两台服务器N1和N2上的数据库DB0的数据是一致的
  • 在满足A的时候,两台服务器N1和N2在收到每次请求都会正常返回响应
  • 在满足P的时候,两台服务器N1和N2任何一方宕机或者网络不同的时候,都不会影响N1和N2彼此之间的正常运行

正常情况下:如果用户通过N1中的应用程序A将数据写到DB0后,将DB0改成DB1,通过分布式系统的数据同步,N2中的DB0也同步更新为了DB1,这时候用户通过应用程序B请求到的数据就是更新完的DB1

异常情况下:如果在上面N1和N2数据同步时出现了网络传输问题(网络不通),但我们要保证分区容错性,那么我们还能同时满足一致性和可用性吗?

N1通过用户更新把DB0改为DB1,这时候网络不通,导致N2数据库还是DB0,如果用户去请求N2中的数据,我们只能请求到旧的数据DB0。我们从一致性和可用性的角度看应该怎么解决:

  • 牺牲C,返回旧的数据DB0
  • 牺牲A,阻塞等待,直到网络恢复,同步完新的数据DB1后再返回

结论:通过这么一个简单的例子,我们可以发现如果要实现一个满足分区容错性的分布式系统,那么只能在一致性和可用性中选择一个。那具体我们应该怎么做取舍呢?

三、CAP模型取舍

在上面的结论里我们知道,CAP模型中无法同时满足,所以我们应该怎么做取舍呢?

取舍的策略有三种,分别是:

  • CA without P:舍弃P意味着不允许分区(也就是单点部署),那就违背了分布式系统设计的初衷,所以是不合适的
  • CP without A:舍弃A意味着要牺牲用户体验(因为要等数据同步完才能正常访问服务),典型的例子就是Redis
  • AP without C:舍弃C意味着也要牺牲用户体验(因为可能返回的数据不是最新的,导致后续操作受影响,但好处是避免了阻塞),典型的例子就是我们在秒杀中看到了库存还充足,但是下单的时候却提示商品已售罄

总结:具体问题具体分析,我们要根据使用场景要选择我们最适合的CAP模型,比如金融系统中对数据比较敏感,就需要保证数据一致性,那么就可能要舍弃可用性了(经常发生的就是某某金融系统宕机了一段时间)。但其他的一般场景,我们还是尽量保证系统的可用性,来避免系统阻塞导致的吞吐量低下问题。


文章作者: GaryLee
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 GaryLee !
  目录