分布式事务
事务:将多个操作封装到一个不可分割的执行单元,只有所有操作都执行成功才提交,只要其中任一操作执行失败,所有操作都回滚。
要么都做,要么都不做。目的是保证数据的一致性。
分布式事务:在分布式系统中保证不同节点之间整体的事务
单机事务的目标是满足ACID,对于分布式事务而言目标是满足CAP
CAP
1、 一致性(Consistency)
客户端的每次读操作,不管访问哪个节点,要么读到的都是同一份最新写入的数据,要么读取失败。
即:要么就不给你,给你的一定是正确的数据
2、可用性(Availability)
任何来自客户端的请求,不管访问哪个非故障节点,都能得到响应数据,但不保证是同一份最新数据
即:我一定会给你数据,但是正确性不保证
3、分区容错性(Partition tolerance) :
通常分布式系统的各个节点部署在不同的子网,这就是网络分区,不可避免的会出现由于网络问题而导致节点之间通信失败,此时不能因为有分区故障了就不提供服务了,仍可对外提供服务就是分区容忍性。
网络分区:
网络分区是指因为网络故障导致网络不连通,不同节点分布在不同的子网络中,各个子网络内网络正常。
形象化理解:
!P:出现分区故障了,系统认为活不下去了,撂挑子。
CP:出现分区故障了,首先我不能撂挑子,我更在乎各节点一致,那我就等等,等到他们一致吧。
AP:出现分区故障了,我也不能撂挑子,我更关心系统的可用性,先不等各节点一致了,干活,错就错了。
P一定要保证,C和A不能兼得
首先,在分布式系统没有发生故障时(绝大多数时候),CAP都是可以保证的,只有当通信故障导致网络分区时,一定要保证P分区容错性(继续提供服务),至于C和A保证那个则根据具体的系统来判断。
所以就有了AP和CP两种选择:具体如何选择呢?
- 如果业务需要强一致性,则只能牺牲可用性而选择CP模型。比如银行转账。
- 如果业务需要最终一致性即可,则优先满足可用性,选择AP模型,大部分互联网场景下选择AP
理解C和A为什么不能兼得:
一个分布式系统里面,节点组成的网络本来应该是连通的。然而可能因为一些故障,使得有些节点之间不连通了,整个网络就分成了几块区域。数据就散布在了这些不连通的区域中。这就叫分区
。
当数据只在一个节点中保存,那么分区出现后,和这个节点不连通的部分就访问不到这个数据了。这时分区就是无法容忍的。提高分区容忍性的办法就是一个数据项复制到多个节点上,那么出现分区之后,这一数据项就可能分布到各个区里。容忍性就提高了。然而,要把数据复制到多个节点,就会带来一致性的问题
。
要保证一致,每次写操作就都要等待全部节点写成功,而这等待又会带来可用性的问题。
总的来说就是,数据存在的节点越多,分区容忍性越高,但要复制更新的数据就越多,一致性就越难保证。为了保证一致性,更新所有节点数据所需要的时间就越长,可用性就越难保证、
ACID:追求CAP中的C
ACID 理论是对事务特性的抽象和总结,方便我们实现事务。
在单机上实现 ACID 不难,比如可以通过锁,但是在分布式系统实现ACID 特性会比较难,因为分布式系统涉及多个节点间的操作。加锁等机制只能保证单个节点上操作的 ACID 特性,无法保证节点间操作的 ACID 特性。
那么怎么做才会让实现不那么难呢?
答案是分布式事务协议,比如二阶段提交协议和 TCC等
BASE:追求CAP中的A
BASE 理论为了支持大型分布式系统,通过牺牲强一致性,保证最终一致性来获得高可用性。互联网基本都是BASE
BASE是:
- Basically Available(基本可用)、
- Soft state(软状态)
- Eventually consistent(最终一致性)
Basically Available(基本可用):指分布式系统在出现故障的时候,允许损失部分可用性(比如响应时间变长)
Soft state(软状态):和硬状态相对,是指允许系统中的数据存在中间状态
,并认为该中间状态的存在不会影响系统的整体可用性,即允许进行数据同步的过程存在延时。
Eventually consistent(最终一致性):最终一致性强调的是系统中所有节点的数据无需实时一致
,最终能够达到一致的状态即可。强一致性是最终一致性的特例,可以理解成没有延迟的最终一致性,
实现最终一致性的方式:
- 读时修复:在读取数据时,检测数据的不一致,进行修复
- 写时修复:在写入数据,检测数据的不一致时,进行修复
- 异步修复:这个是最常用的方式,定时检测副本数据的一致性,并修复。
BASE是对CAP中一致性和可用性
权衡的结果,是从AP演化而来的,其核心思想是即使无法做到强一致性
,但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性
。