织梦cms如何做网站,万网网站备份,推广服务商,市场营销网络1. CAP 的由来
要理解 CAP#xff0c;首先我们要清楚#xff0c;为何会有人提出 CAP#xff1f;他提出 CAP 是为了解决什么问题#xff1f;
时间回到 1985 年#xff0c;彼时#xff0c;后来证明了 CAP 理论的 Lynch 教授此时给当时的 IT 界来了一记惊雷#xff1a;
…1. CAP 的由来
要理解 CAP首先我们要清楚为何会有人提出 CAP他提出 CAP 是为了解决什么问题
时间回到 1985 年彼时后来证明了 CAP 理论的 Lynch 教授此时给当时的 IT 界来了一记惊雷
她通过不可辩驳的证明告诉业界的工程师们如果在一个不稳定消息要么乱序要么丢了的网络环境里分布式异步模型想始终保持数据一致是不可能的。
这是个什么概念呢就是她打破了那些既想提供超高质量服务又想提供超高性能服务的技术人员的幻想。
这本质是在告诉大家在分布式系统里需要妥协。
但是如何妥协分布式系统里到底应该怎么权衡这种 trade-off
我们可以想象一下在 CAP 定理提出之前没有这些方向性的指引在设计和实施分布式系统时该有多么混乱。一套分布式系统是由多个模块组成的这些模块本身可能由不同的开发人员去完成。然而对于这些人在公共层面竟然没有一个原则去指导他们该怎么完成这套功能。
比如我们在同步两个节点的数据时如果发生了错误到底我们应该怎么做呢如果没有统一的标准和方向那很可能在一套分布式系统中的不同模块会出现不同的处理情况。
假设一套系统由 A、B 两个模块构成。
A 模块的设计理念是节点间出现了问题它可能会选择不断的重试一直等到节点通信恢复。
而 B 的设计理念是节点间出现了问题它断开就是了可能最多就记录下状态等以后处理。
可是当 A、B 之间出现了通信怎么办那会出现 A 往 B 发请求出问题会不断重试。而 B 往 A 发请求出问题则直接断开的情况。
当然在后面我们会说明CAP 的理念在实际工程中会允许这种不一致。可是那种不一致是提前设计好和规划好的是根据实际数据的重要性和业务需求做的妥协而不是这种混乱的妥协。
所以IT 界的人们就一直在摸索试图找到一些纲领去指导分布式系统的设计这一找就找了 15 年。
2000 年时Eric Brewer 教授在 PODC 会议上提出了 CAP 理论但是由于没有被证明过所以当时只能被称为 CAP 猜想。这个猜想引起了巨大的反响因为 CAP 很符合人们对设计纲领的预期。
在 2002 年后经过 Seth Gilbert 和 Nancy Lynch 从理论上证明了 CAP 猜想后CAP 理论正式成为了分布式系统理论的基石之一。
2. CAP 到底是什么
CAP 定理表达了一个分布式系统里不可能同时满足以下的三个特性
2.1. C数据一致性
什么是数据一致性咋一看真的很让人糊涂一致性是什么是指数据能一起变化是能让数据整齐划一。
那么问题又来了数据何时会变化数据怎么才能被称为一起变化我们现在来回答这些问题当我们搞清楚了这些问题那么对数据一致性就会有了清晰的理解。
首先第一个问题数据何时会一起变化
答案是仅且仅当包含数据的服务收到数据更新请求的时候数据才会发生变化。而数据更新请求则仅包括数据的增、删、改这三种请求而这三种请求又被统称为写请求。所以数据只有在写请求的时候才会发生变化。
那我们来回答第二个问题数据要怎么样才能被称为一起变化了即谁来判断数据是最终变化了是服务器对写请求的返回结果吗告诉写请求成功数据就一定发生一致性变化了
NO数据发生变化是否一致是需要经过读请求来做检验的。那么读请求判断的依据是什么呢
假设我们的分布式存储系统有两个节点每个节点都包含了一部分需要被变化的数据。如果经过一次写请求后两个节点都发生了数据变化。然后读请求把这些变化后的数据都读取到了我们就把这次数据修改称为数据发生了一致性变化。
但是这还不是完整的一致性。因为系统不可能永久的正常运行下去。
如果系统内部发生了问题从而导致系统的节点无法发生一致性变化会怎么样呢当我们这样做的时候就意味着想看到最新数据的读请求们很可能会看到旧数据或者说获取到不同版本的数据。此时为了保证分布式系统对外的数据一致性于是选择不返回任何数据。
这里需要注意一下CAP 定理是在说在某种状态下的选择和实际工程的理论是有差别的。上面描述的一致性和 ACID 事务中的一致性是两回事。事务中的一致性包含了实际工程对状态的后续处理。但是 CAP 定理并不涉及到状态的后续处理对于这些问题后续出现了 BASE 理论等工程结论去处理目前只需要明白 CAP 定理主要描述的是状态。
2.2. A可用性
奥维德曾经说过“行动被人们遗忘结果却将永存”。
这句话说明了结果的重要性而可用性在 CAP 里就是对结果的要求。它要求系统内的节点们接收到了无论是写请求还是读请求都要能处理并给回响应结果。只是它有两点必须满足的条件
条件 1返回结果必须在合理的时间以内这个合理的时间是根据业务来定的。业务说必须 100 毫秒内返回合理的时间就是 100 毫秒需要 1 秒内返回那就是 1 秒如果业务定的 100 毫秒结果却在 1 秒才返回那么这个系统就不满足可用性。
条件 2需要系统内能正常接收请求的所有节点都返回结果。这包含了两重含义 如果节点不能正常接收请求了比如宕机了系统崩溃了而其他节点依然能正常接收请求那么我们说系统依然是可用的也就是说部分宕机没事儿不影响可用性指标。 如果节点能正常接收请求但是发现节点内部数据有问题那么也必须返回结果哪怕返回的结果是有问题的。比如系统有两个节点其中有一个节点数据是三天前的另一个节点是两分钟前的如果一个读请求跑到了包含了三天前数据的那个节点上抱歉这个节点不能拒绝必须返回这个三天前的数据即使它可能不太合理。
2.3. P分区容忍性
分布式的存储系统会有很多的节点这些节点都是通过网络进行通信。而网络是不可靠的当节点和节点之间的通信出现了问题此时就称当前的分布式存储系统出现了分区。但是值得一提的是分区并不一定是由网络故障引起的也可能是因为机器故障。
比如我们的分布式存储系统有 A、B 两个节点。那么当 A、B 之间由于可能路由器、交换机等底层网络设备出现了故障A 和 B 通信出现了问题但是 A、B 依然都在运行都在对外提供服务。这时候就说 A 和 B 发生了分区。
还有一种情况也会发生分区当 A 出现了宕机A 和 B 节点之间通信也是出现了问题那么我们也称 A 和 B 发生了分区。
综上我们可以知道只要在分布式系统中节点通信出现了问题那么就出现了分区。
那么分区容忍性是指什么 它是说如果出现了分区问题我们的分布式存储系统还需要继续运行。不能因为出现了分区问题整个分布式节点全部就熄火了罢工了不做事情了。
3. CAP 怎么选择
我们上面已经知道了在设计分布式系统时架构师们在 C、A、P 这三种特性里只能选择两种。
但是这道 CAP 的选择题就像别人在问你“小明的父亲有三个孩子老大叫大朗老二叫二郎请问老三叫什么”一样。在以分布式存系统为限定条件的 CAP 世界里P 是早已经确定的答案P 是必须的。
因为在分布式系统内P 是必然的发生的不选 P一旦发生分区错误整个分布式系统就完全无法使用了这是不符合实际需要的。所以对于分布式系统我们只能能考虑当发生分区错误时如何选择一致性和可用性。
而根据一致性和可用性的选择不同开源的分布式系统往往又被分为 CP 系统和 AP 系统。
当一套系统在发生分区故障后客户端的任何请求都被卡死或者超时但是系统的每个节点总是会返回一致的数据则这套系统就是 CP 系统经典的比如 Zookeeper。
如果一套系统发生分区故障后客户端依然可以访问系统但是获取的数据有的是新的数据有的还是老数据那么这套系统就是 AP 系统经典的比如 Eureka。
说了这么多其实 CAP 定理本质很简单它就是一种分布式系统设计的不同理念概括包括它说的一致性可用性和分区容错性。这就类似一个大学的校训是极度概念化的东西。
所以大白话来形容下 CAP 吧CAP 就是告诉程序员们当分布式系统出现内部问题了你要做两种选择
要么迁就外部服务像外包公司。要么让外部服务迁就你像银行。
迁就外部服务就是我们不能因为我们自己的问题让外部服务的业务运行受到影响所以要优先可用性。而让外部服务迁就我们就要优先一致性。
4. 对 CAP 的常见误解
误解一分布式系统因为 CAP 定理放弃了 C 或者 A 中的其中一个
很多人在没有对 CAP 做深入了解的情况下听到很多人说分布式系统必须在 CAP 三个特性里选择两个就觉得一套分布式系统肯定要么只有可用性要么只有一致性不存在完整的可用性和一致性功能。
这种理解是大有问题的。因为P 这种问题发生的概率非常低所以
当没有出现分区问题的时候系统就应该有完美的数据一致性和可用性。
你什么时候见过一个系统当内部没有问题的时候会经常让外部请求卡一下的要么就冷不丁的提供陈旧的老数据那还能叫系统吗
误解二C 和 A 之间的选择是针对整个分布式系统的只能整体考虑 C 和 A 之间的选择
这个理解也是不对的。当分区发生的时候其实对一致性和可用性的抉择是局部性的而不是针对整个系统的。
可能是在一些子系统做一些抉择甚至很可能只需要对某个事件或者数据做一致性和可用性的抉择而已。
比如当我们做一套支付系统的时候会员的财务相关像账户余额账务流水是必须强一致性的。这时候你就要考虑选 C。但是会员的名字会员的支付设置就不必考虑强一致性可以选择可用性 A。
一套分布式系统的运行就像人生一样就是一次又一次的选择。在不同阶段不同的时刻有不同的事件发生的时候又怎么可能会有完全一样的选择呢
误解三CAP 的三个特性只有是和否两种极端选择而不是一个范围
这种二元性的理解更是极其误导人。
CAP 理论的三种特性不是 Boolean 类型的不是一致和不一致可用和不可用分区和没分区的这类二选一的选项。而是这三种特性都是范围类型。
拿可用性来说就像我从银行取钱。当我目的是派发压岁钱的时候我很可能就想全要新票子但是新票子很可能就还得多一个步骤就是需要拿旧票子去换一些新票此时我可以多等会儿能拿到新票子就好。而当我的目的就是做生活花销的时候票子是新是旧我根本不那么关心快点拿到钱就行。这就是可用性的范围需求之一对时延性的要求。
再比如分区容错则由于探测机制的问题可能还得各节点搞投票去协商分区是否存在当某一台机器出现了问题可能不影响业务的话就会被机器投票认为分区不存在。然后一直等到多数机器出现了问题才会投票确认出现了分区问题。这就好像新冠疫情还会分低、中、高风险区呢不是一出现通信故障就都被逻辑认定为分区问题。
5. CAP 理论的一些疑问
疑问一在遵从 CAP 定理的系统中是否适合任意的写请求
首先在 CAP 定理中关于一致性会有多种说法但是总的来说都是在描述数据最新版本的可见性。而这些可见性往往代表的是读请求返回的数据的可见性。
那么问题来了当我们要求读数据的可见性的时候对写数据有什么要求吗
比如我们系统有三个节点一个客户端给这个系统发了一个写请求要求系统写入一个值为 20 的数据。那么如果要满足 CAP 定理中的一致性就需要在写完 20 这个数据之后当其他客户端请求读取这个值为 20 的数据之后无论请求被转发到系统中任何节点都能返回这个值。
这就要求写入这个值为 20 的写请求必须成功写到三个节点上此时系统就满足了写一致性的。所以我们可以说对于读一致性的要求是同时约束了写一致性的。
其次在 CAP 定理中可用性本身要求对读、写请求都要处理。如果我们以可用性作为标准的时候在发生分区错误时由于我们对读请求并没有强行要求返回完全准确的数据所以可能在本次读请求之前的最近一次写请求可能是部分失败的。
同样的例子我们的分布式系统由三个节点组成最近一次写请求想把值为 20 的数据写到三个节点上。但是由于发生了分区问题有一个节点通信故障写请求写不过去因此只有两个节点包含了值为 20 的数据。
此时写请求会返回给客户端一个结果可能会告诉客户端写入成功了也可能告诉客户端写入部分成功。
这时候当后续的读请求恰巧被发送到有通信故障的那个节点系统可能只能返回一个空的结果。但是由于系统处理和返回了读写请求所以系统是满足了 CAP 中的可用性的。
疑问二数据分片和数据副本的分布式系统是否都遵守 CAP 定理
我们知道在一套大规模的分布式系统里一定是既需要把海量数据做切分存储到不同的机器上也需要对这些存储了数据的机器做副本备份的。
那么如果一个分布式系统里只有数据分片存储或者只有数据副本存储他们都会遵守 CAP 定理吗
答案是当数据分片时也是要遵守 CAP 定理但是是种非常特殊的遵守。
当在一套分布式系统只有分片存储的时候CAP 理论会表现成什么样
比如我们有个分布式系统由三个节点 a、b、c 组成。其中节点 a 存放了 A 表的数据b 存放了 B 表的数据c 存放了 C 表的数据。
如果有一个业务它的意图是想往 A 表插入一条新数据在 B 表删除一条已有数据在 C 表更新一条老数据这个分布式系统该怎么处理这种业务
技术上我们对这种一个意图想做多件事的情况往往会包装成一个事务。当我们包装成一个事务以后我们可能会通过先在 a 节点执行然后去 b 节点执行最后去 c 节点执行等到都成功了才会返回成功。
但是发生了分区以后怎么办当在 a、b 节点都成功了到 c 发现发生了通信故障
此时根据 CAP 定理你有两个选择要么就直接返回一个部分成功的结果给客户端要么直接卡死等客户端超时或者返回失败给客户端。当返回部分成功的时候这就是选择了可用性A当卡死或者返回失败给客户端的时候就是选择了一致性C。
可是我们将请求包装成了事务而事务是要求要么都成功要么都失败……为了遵守这种要求对于分布式只有分片的情况迫于客观条件只能选择C。所以分片的分布式系统往往都是 CP 的系统。
可选择但是无法选择是分布式系统只有分片数据存储的情况时遵守 CAP 定理的特殊表现。
而当分布式系统是多个节点每个节点存储了完整的一套数据别的节点只是完整数据的备份的时候即使事务只在一台机器上成功当发生分区故障的时候我们也是可以有充分的余地选择是单机事务的回退 or 就此认为写成功的。
单机事务的回退就可以对外表现为选择了一致性。
就此认为写成功则可以认为选择了可用性。
疑问三为何有时候区分一个系统是 AP 还是 CP 是如此之难
因为就像我们前面讲过的由于 AP 或者 CP 的选择可能仅局限为整套系统的局部甚至某些特殊的数据上而我们又是用这种局部的特性去描述了整套系统所以就导致了区分的困难。而这本身其实也日渐成为了 CAP 的一个大问题从而被人诟病。
6. CAP 的不足 CAP 定理本身是没有考虑网络延迟的问题的它认为一致性是立即生效的但是要保持一致性是需要时间成本的这就导致往往分布式系统多选择 AP 方式 由于时代的演变CAP 定理在针对所有分布式系统的时候出现了一些力不从心的情况导致很多时候它自己会把以前很严谨的数学定义改成了比较松弛的业务定义类似于我们看到CAP 定理把一致性、可用性、分区容错都变成了一个范围属性而这和 CAP 定理本身这种数学定理般的称呼是有冲突的出现了不符合数学严谨定义的问题。 在实践中以及后来 CAP 定理的提出者也承认一致性和可用性并不仅仅是二选一的问题只是一些重要性的区别当强调一致性的时候并不表示可用性是完全不可用的状态。比如Zookeeper 只是在 master 出现问题的时候才可能出现几十秒的不可用状态而别的时候都会以各种方式保证系统的可用性。而强调可用性的时候也往往会采用一些技术手段去保证数据最终是一致的。CAP 定理并没有给出这些情况的具体描述。 CAP 理论从工程角度来看只是一种状态的描述它告诉大家当有错的时候分布式系统可能处在什么状态。但是状态是可能变化的。状态间如何转换如何修补如何恢复是没有提供方向的。
7. 引申出来的 BASE
正因为 CAP 以上的种种不足epay 的架构师 Dan Pritchett 根据他自身在大规模分布式系统的实践经验总结出了 BASE 理论。BASE 理论是对 CAP 理论的延伸核心思想是即使无法做到强一致性Strong Consistency但应用可以采用适合的方式达到最终一致性Eventual Consitency。
BASE 理论是实践工程的理论它弥补了CAP 理论过于抽象的问题也同时解决了 AP 系统的总体工程实践思想是分布式系统的核心理论之一我们将在下一篇文章里详细的讲解此套理论。
8. 大厂面试题
在文章最后来几道大厂关于 CAP 的面试真题检验一下你的学习效果hiahiahia 什么是 CAP 理论 CAP 中的 P 是什么意思 为什么说分布式系统只能在 C、A 中二选一 结合实际应用CP、AP 该怎么选择
资料分享
这是我从某优质机构弄来的一些资料内容我认为确实称得上优质二字如需领取请点赞这篇文章关注我然后点击这里即可免费领取
首先分享一份学习大纲内容较多涵盖了互联网行业所有的流行以及核心技术以截图形式分享
亿级流量性能调优实战一线大厂分布式实战架构师筑基必备技能设计思想开源框架解读性能直线提升架构技术高效存储让项目性能起飞分布式扩展到微服务架构…实在是太多了 其次分享一些技术知识以截图形式分享一部分
Tomcat架构解析 算法训练高分宝典 Spring CloudDocker微服务实战 最后分享一波面试资料 切莫死记硬背小心面试官直接让你出门右拐 1000道互联网Java面试题 Java高级架构面试知识整理 [外链图片转存中…(img-usGqwic6-1625414623446)]
Spring CloudDocker微服务实战
[外链图片转存中…(img-Nay6GB6l-1625414623447)]
最后分享一波面试资料 切莫死记硬背小心面试官直接让你出门右拐 1000道互联网Java面试题
[外链图片转存中…(img-c26Kf019-1625414623447)]
Java高级架构面试知识整理
[外链图片转存中…(img-z7ETdpgX-1625414623448)]