对CAP理论的理解

简介: 对CAP理论的理解

介绍


最近经常看到有人发一个Go实现的分布式事务管理器dtm,看到star增的挺猛的,索性看看代码实现,毕竟工作中部分场景也用的上。

在写源码分析之前,我们先来简单入门一下分布式理论。

1668513063348.jpg


CAP


分布式系统中很大的一个难点在于各个节点之间的状态如何同步,CAP就是分布式系统领域一条已经被证明的定律。


其中各个字母的含义如下:

  • Consistency(一致性)
  • Availability(可用性)
  • Partition tolerance(分区容忍性)


我们先用一个简单的例子来说明


1668513078598.jpg


假设我们的系统是由两个服务组成的:G1和G2。


G1和G2维护了同一条记录V0。外部客户端(Client)可以调用任意一个服务。


当一个客户端对任意一个服务发起读|写请求,那么被请求的那个服务器根据客户端的请求,处理、响应结果。

比如客户端向G1发起一个读操作,客户端G1响应请求


1668513100024.jpg


又比如客户端向G1发起一个写操作,把V0修改成V1。


1668513109480.jpg


到这里,我们建立了这样一个系统。接下来看看系统的一致性、可用性和分区容忍性意味着什么。


Consistency(一致性)


这个一致性和事务中ACID中的C还是有区别的。事务中的C更多是指在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这里的完整性包括一些外键约束、键的唯一性等。


而分布式事务中的C指的是,写操作之后的读操作,必须返回该值,这就等同于所有节点访问的是同一份最新数据的副本。


下面是一个非一致性的例子


1668513129089.jpg


客户端成功请求G1服务器写V1。假设当前服务G1和G2不能互通(网络分区),导致G1数据不能同步到G2,此时客户端从G2读取数据,依旧返回V0。


来看一个满足一致性的例子。


1668513138532.jpg


在这个系统中,G1收到客户端写V1的操作,G1在修改自身数据的同时,会把V1数据同步到G2。G1在收到G2的响应后,才向客户端响应结果。这样,之后无论客户端从哪个节点读取数据,都能获取到V1值


Availability(可用性)


可用性指的是系统中非故障节点接收到的每一个请求都必须响应。

在一个可用的系统中,如果客户端向服务器发送一个请求,那么服务器必须响应客户端每一个请求,不允许忽略客户端请求


Partition Tolerance(分区容忍性)


什么分区?

网络分区。

网络分区咋么理解

假设有两台服务器A和B,本来他们两是正常通信的,不知道啥原因,他们之间的网络链接断开,导致无法正常通信。此时本来在同一个网络的AB,发生了网络分区。变成了A所在的A网络和B所在的B网络。这就是网络分区。

容忍性是指什么?

当一个服务的多台服务器发生上述网络分区的时候,系统依旧能正常提供服务


对CAP的误解


网上很多文章都是这么说的

一个分布式系统最多只能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三项中的两项,这被称为CAP定律。

似乎CAP被解释成一种三选二的定律。


看到一篇文章CAP Twelve Years Later: How the "Rules" Have Changed[1]有一段CAP的完整表述:

The CAP theorem asserts that any net­worked shared-data system can have only two of three desirable properties。

按照表述,发现网上这句话存在一定的误导性。


CAP定律的前提是P(网络分区)发生后,才会有CA的选择。

当P发生的时候,而我们的系统直接不服务了,那就不存在选择什么CA了。


因此CAP的正常理解应该是:当P(网络分区)发生的时候,如果我们要继续提供服务,那么C(一致性)和A(可用性)只能2选1了。


Consistency和Availability的矛盾


为什么当P发生时,CA只能二选一?


还是之前那个简单的例子。

假设此时G1和G2发生了网络分区


1668513172819.jpg


接下来我们的客户端请求G1写V1数据。由于分区,G1不能同步数据到G2


1668513184776.jpg

1668513191374.jpg


如果我们保证G2的可用性,那么当客户端请求G2数据的时候,G2能正常响应V0数据,但是数据和G1不一致,无法保证一致性。


如果我们保证G2的一致性,那么在G1写操作的时候,就必须锁定G2的读写操作,那么此时G2就处于不可用状态,无法保证其可用性。

因此,Consistency和Availability存在矛盾


参考



相关文章
使用LamdbaUpdateWrapper的setSql作用及风险
使用LamdbaUpdateWrapper的setSql作用及风险
使用LamdbaUpdateWrapper的setSql作用及风险
|
机器学习/深度学习 网络架构
浅谈神经网络中的bias
1、什么是bias? 偏置单元(bias unit),在有些资料里也称为偏置项(bias term)或者截距项(intercept term),它其实就是函数的截距,与线性方程 y=wx+b 中的 b 的意义是一致的。在 y=wx+b中,b表示函数在y轴上的截距,控制着函数偏离原点的距离,其实在神经网络中的偏置单元也是类似的作用。 因此,神经网络的参数也可以表示为:(W, b),其中W表示参数矩阵,b表示偏置项或截距项。
1563 0
浅谈神经网络中的bias
|
7月前
|
存储 人工智能 API
OWL:告别繁琐任务!开源多智能体系统实现自动化协作,效率提升10倍
OWL 是基于 CAMEL-AI 框架开发的多智能体协作系统,通过智能体之间的动态交互实现高效的任务自动化,支持角色分配、任务分解和记忆功能,适用于代码生成、文档撰写、数据分析等多种场景。
1537 13
OWL:告别繁琐任务!开源多智能体系统实现自动化协作,效率提升10倍
|
10月前
|
存储 安全 Java
Java 集合框架中的老炮与新秀:HashTable 和 HashMap 谁更胜一筹?
嗨,大家好,我是技术伙伴小米。今天通过讲故事的方式,详细介绍 Java 中 HashMap 和 HashTable 的区别。从版本、线程安全、null 值支持、性能及迭代器行为等方面对比,帮助你轻松应对面试中的经典问题。HashMap 更高效灵活,适合单线程或需手动处理线程安全的场景;HashTable 较古老,线程安全但性能不佳。现代项目推荐使用 ConcurrentHashMap。关注我的公众号“软件求生”,获取更多技术干货!
162 3
|
安全 Java API
为什么捕获异常后不要使用e.printStackTrace()打印日志
为什么捕获异常后不要使用e.printStackTrace()打印日志
|
机器学习/深度学习 人工智能 TensorFlow
利用AI技术实现智能垃圾分类
【8月更文挑战第67天】随着人工智能技术的不断发展,越来越多的应用场景开始涌现。本文将介绍如何利用AI技术实现智能垃圾分类,通过代码示例和实际应用案例,帮助读者了解AI技术在垃圾分类领域的应用价值和潜力。
827 19
|
缓存 Linux 虚拟化
Linux下top命令指标说明
Linux下top命令指标说明
741 0
|
安全 关系型数据库 MySQL
|
SQL Oracle 关系型数据库
SQL添加字段记录详解:技巧与方法实践
在数据库管理中,经常需要向表中添加新的字段(列)或向现有字段中插入新的记录(行)
2650 0
|
负载均衡 Cloud Native 容灾
阿里云负载均衡SLB价格_ALB、NLB和CLB区别_负载均衡详细介绍
阿里云负载均衡SLB提供ALB、NLB和CLB三种类型,分别适用于7层和4层的不同场景。ALB与NLB仅支持按量付费,而CLB则额外提供包年包月选项。ALB强调7层应用处理与高级路由,NLB聚焦4层的大流量处理与SSL卸载。两者均支持自动弹性伸缩,确保高可用性和性能。CLB作为传统负载均衡,适用于特定需求。每种类型依据实例规格与使用量收费,其中公网实例还需支付网络费用。通过这些服务,用户可以实现流量分发、故障转移及提升应用系统的稳定性和扩展性。