当前位置: 首页 > 科技观察

一起来谈谈对CAP理论的理解

时间:2023-03-14 20:55:45 科技观察

介绍最近经常看到有人发一个用Go实现的分布式事务管理器dtm。看到star上升很快,我们简单看一下代码实现。毕竟部分作品的场景也是用到的。在写源码分析之前,先简单介绍一下分布式理论。CAP分布式系统的一大难点是如何同步节点之间的状态。CAP在分布式系统领域是一条行之有效的法则。每个字母的含义如下:Consistency(一致性)Availability(可用性)Partitiontolerance(分区容忍度)让我们用一个简单的例子来说明。假设我们的系统由两个服务组成:G1和G2。G1和G2维护同一条记录V0。外部客户(Client)可以调用任何服务。当客户端向任何服务发起读|写请求时,被请求的服务器根据客户端的请求对结果进行处理和响应。例如客户端向G1发起读操作,客户端G1响应请求。又如客户端向G1发起写操作,将V0变为V1。至此,我们已经构建了这样一个系统。让我们看看系统的一致性、可用性和分区容忍性意味着什么。一致性(Consistency)这种一致性在ACID中还是和C在事务中有所不同。事务中的C更多是指在事务开始前和事务结束后数据库的完整性不被破坏。这里的完整性包括一些外键约束,键的唯一性等。分布式事务中的C是指写操作之后的读操作必须返回这个值,相当于所有的节点都访问同一份最新数据。下面是一个不一致的例子。客户端成功请求G1服务器写入V1。假设当前服务G1和G2无法互通(网络分区),导致G1数据无法同步到G2。此时客户端从G2读取数据,仍然返回V0。我们来看一个满足一致性的例子。在这个系统中,G1接收到客户端写V1的操作,G1会在修改自己的数据的同时将V1的数据同步给G2。G1只有在收到G2的响应后才响应客户端。这样,无论客户端以后从哪个节点读取数据,都可以获得V1的值。可用性(availability)可用性是指系统中非故障节点收到的每一个请求都必须得到响应。在可用的系统中,如果客户端向服务器发送请求,服务器必须响应客户端的每一个请求,不允许忽略客户端请求。PartitionTolerance(分区容差)什么分区?网络分区。你怎么理解网络分区?假设有两台服务器A和B,它们可以正常通信。由于某种不明原因,它们之间的网络链接断开,导致无法正常通信。这时,原本在同一网络的AB出现了网络分区。变成A所在的A网络和B所在的B网络。这就是网络分区。宽容是什么意思?当一个服务的多个服务器出现上述网络分区时,系统仍然可以正常提供服务。对CAP的误解网上很多文章都是这样说的:分布式系统最多只能满足一致性(Consistency)、可用性(Availability)和分区容忍度(Partitiontolerance)三项中的两项。称为CAP法。似乎CAP被解释为一种三取二定律。请参阅文章CAP十二年后:“规则”如何改变[1]有一个完整的CAP陈述:CAP定理断言任何网络共享数据系统只能具有三个理想属性中的两个。根据声明,发现网上的这句话有些误导。CAP定律的前提是P(网络分区)发生后,会出现CA的选择。当P发生时,我们的系统不直接服务,就没有CA的选择。所以对于CAP的正常理解应该是:当P(网络分区)发生时,如果我们还想继续提供服务,那么C(一致性)和A(可用性)只能二选一。一致性和可用性的矛盾为什么当P发生时,CA只能二选一?还是之前那个简单的例子。假设此时G1和G2之间发生了网络分区。接下来我们的客户端请求G1写入V1数据。由于分区,G1无法同步数据到G2。如果我们保证G2的可用性,那么当client请求G2数据时,G2可以正常响应V0数据,但是数据与G1不一致,无法保证一致性。如果我们保证G2的一致性,那么当G1写的时候,G2的读写操作必须加锁,那么此时G2就处于不可用状态,它的可用性得不到保证。因此,一致性和可用性之间存在矛盾。参考https://www.infoq.com/articles/cap-twelve-years-later-how-the-rules-have-changed/https://mwhittaker.github.io/blog/an_illustrated_proof_of_the_cap_theorem/https://www.zhihu.com/question/64778723