分布式基础-CAP理论

对于刚进入分布式领域的你来说,常会怀有一系列错误的假设。
基本上每个人都会预设下面的8条假定:

  1. 网络是稳定的
  2. 网络传输的延迟是零
  3. 网络的带宽是无穷大
  4. 网络是安全的
  5. 网络的拓扑不会改变
  6. 只有一个系统管理员
  7. 传输数据的成本是零
  8. 整个网络是同构的

而有了这些错误假定,就是系统设计悲剧的开始。

相应地,为了设计好一个分布式系统,你应该牢记以下的前提:

  1. 网络不总是稳定的
  2. 网络传输的延迟不可能为零
  3. 网络的带宽是有限的,要充分利用
  4. 网络的默认设置是非安全的
  5. 网络的拓扑会改变
  6. 会有多个系统管理员
  7. 传输数据的成本是需要考虑的
  8. 整个网络是非同构的

为啥要有CAP

有了以上的8条前提,可以想象设计一个好的分布式系统是非常困难的。
当你遇到巨大难题的时候,如果有人提纲挈领的给一个指导,那么想必你的工作会顺利不少。
那么在业界,存不存在这样的理论指导呢?
当然是有的,这要感谢Eric Brewer教授,他在2000年7月,提出了著名的CAP猜想:

在一个不稳定(消息要么乱序要么丢了)的网络环境里(分布式异步模型),能否始终保持数据一致

2年后,Seth Gilbert和Nancy Lynch从理论上证明了CAP理论,原始论文请点击查看

CAP理论告诉你,不要幻想了,在分布式环境中,不能既要...又要...还要,做系统要有所取舍。

什么是CAP

CAP分别表示:

  • 一致性(Consistency):也就是一个副本修改数据时,其他副本也要更新;一般用到的方式是:等其他副本也写入完成,才算真正写入成功
  • 可用性(Available):是指系统提供的服务必须一直处于可用的状态,对于用户的每一个操作请求总是能在有限时间内返回结果
  • 分区容错(Partition Tolerance):是指分布式系统在遇到任何网络分区故障的时候,仍然需要能保证对外提供满足一致性和可用性的服务,除非是整个网络环境都发生了故障

用图片表示是这样的:
image

这里就不给出CAP理论的证明了,我们主要来讨论CAP理论的应用

为何选择CA:放弃分区容错性,加强一致性和可用性

选择CA的系统,就是要放弃分区容错,那么简单理解,可以说你放弃了系统是分布式的,而追求一个单体架构。
最容易想到的就是单节点的关系型数据库,保持了强一致性和可用性,但天生不支持分布式。
那不禁要问,没有了分区容忍,还叫分布式系统么? 确实不能叫分布式系统了。
其实对于分布式系统工程实践,CAP 理论更合适的描述是:在满足分区容错的前提下,没有算法能同时满足数据一致性和服务可用性。

为何选择CP:放弃可用性,或部分可用

对于做网站的工程师来说,CP是最先被摒弃的模式。因为可用性对网站来说是生命线,运维同学对此应该深有体会,如果网站服务宕机,那将是最严重的生产事故。
那么放弃可用性,就没有存在的场景了么?
大千世界,如此复杂,肯定还是会有CP发展的空间的。比如说银行系统来说,一致性是其生命线,分区容错也是要保证的,这时候允许出现不可用,当出现故障的时候,客户需要耐心等待一下,但是金融数据绝对不能出错。

同时你还需要注意到,关于可用性,其中有一些弹性空间的。也就是好的系统,会出现部分不可用,而不是完全不可用。这方面,著名的Paxos就是其中翘楚。

Paxos

Mike Burrows说世界上只有一种一致性算法,就是Paxos。
Paxos算法基本上是一个民主选举算法--大多数的决定会成为整个集群的统一决定。任何一个点都可以提出要修改某个数据的提案,是否通过这个提案取决于这个集群中是否有超过半数的结点同意。
在业界,Paxos算法因为Google的chubby和ZooKeeper而被人熟知。

关于Paxos算法的详解,参考维基百科
其实Zookeeper也未完全实现Paxos,而是使用了ZAB协议,参考Zookeeper协议篇-Paxos算法与ZAB协议

为何选择AP:放弃一致性,追求分区容错性和可用性

你首先要明确,CAP中的C值得是强一致性,也就是要求多节点组成的被调要能像单节点一样运作、操作具备原子性,数据在时间、时序上都有要求。
前面讲到的可用性,显然是在 0% 到 100% 之间连续变化的。对于一致性来说,也是如此,大多数情况下,工程实现上是灵活的,一致性也可以分为多个不同的含义。

  • Weak 弱一致性:当你写入一个新值后,读操作在数据副本上可能读出来,也可能读不出来。比如说一些日志系统
  • Eventually 最终一致性:当你写入一个新值后,有可能读不出来,但在某个时间窗口之后保证最终能读出来。比如说事务补偿
  • Strong 强一致性:新的数据一旦写入,在任意副本任意时刻都能读到新值。比如说文件系统

当可用性和一致性含义增加的时候,情况变得复杂了。
你做系统设计的时候,要根据自己的业务系统选择适当的方式来实现最终的目标,这就需要创意思考,谨慎权衡了。
这也是为什么做架构设计的时候会有3种或以上的方案,多个技术方案进行评审无疑会增强决策的准确性,减少出错概率。

BASE理论

既然可用性和一致性是灵活的,业界也发展出来了基于CAP的其他最佳实践,BASE就是其中的代表。
BASE是Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)三个短语的缩写,他的核心思想是:强一致性是困难的,那么就要根据业务特定,采用适当的方式来使系统达到最终一致性。

  • 基本可用:是指分布式系统在出现不可预知的故障时,允许损失部分可用性。例如响应时间的损失、功能上的损失
  • 软状态:是指允许系统数据存在的中间状态,并认为该中间状态的存在不影响系统的整体可用性,及允许系统主机间进行数据同步的过程存在一定的延时。软状态,其实就是一种灰度状态,过渡状态。
  • 最终一致性:其强调的是系统中所有的数据副本,在经过一段时间的同步后,最终能达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性

对于BASE理论的应用,工程实践可以参考Eureka原理

跳出CAP

CAP只是一种理论指导,有了他,你对问题理解的更加深刻,但也不意味着你就要固步自封了。
跳出CAP,思路延伸为如何规划分区期间的操作和分区之后的恢复。例如,Oracle数据库的DataGuard复制组件包含三种模式:

  • 最大保护模式(Maximum Protection):即强同步复制模式,写操作要求主库先将操作日志(数据库的 redo/undo 日志)同步到至少一个备库才可以返回客户端成功。这种模式保证即使主库出现无法恢复的故障,比如硬盘损坏,也不会丢失数据;
  • 最大性能模式(Maximum Performance):即异步复制模式,写操作只需要在主库上执行成功就可以返回客户端成功,主库上的后台线程会将重做日志通过异步的方式复制到备库。这种方式保证了性能及可用性,但是可能丢失数据;
  • 最大可用性模式(Maximum Availability):上述两种模式的折中。正常情况下相当于最大保护模式,如果主备之间的网络出现故障,切换为最大性能模式。

这就是一种经典的用法。
你会发现,在很多时候通过细致地管理分区期间的不变性约束,两方面的性质都可以取得最佳的表现。

总结

回到最初的问题,CAP理论就像是经济学中蒙代尔不可能三角一样,带你进入了更高的层面分析问题,让你知道设计一个系统时的基础约束,前辈走过了很多路,帮你剔除了很多错误答案,接下来的路上就要靠你自己了。
本文的分析和总结也是挂一漏万,要多研究现有的优秀分布式系统,分析其设计理念和对CAP的实现,你才可以更快地成长。

祝你变得更强!

posted @ 2023-08-04 15:53  轩辕李  阅读(8)  评论(0编辑  收藏  举报