分布式系统CAP理论-分布式事务一致性

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

Consistency 一致性(涉及重要信息如钱财;分布式存储系统必须保证)

从客户端角度,多进程并发访问时,更新过的数据在不同进程如何获取的不同策略,决定了不同的一致性:

1.强一致性:对于关系型数据库,要求更新过的数据能被后续的访问都能看到.

2.弱一致性:能容忍后续的部分或者全部访问不到。

3.最终一致性:经过一段时间后要求能访问到更新后的数据。

CAP中说,不可能同时满足的这个一致性指的是强一致性。

Availability 可用性(大型互联网为了服务可用,舍弃强一致性,保证最终一致性)

服务一直可用,而且是正常响应时间。

Partition Tolerance分区容错性(分布式必须要考虑的问题)

分布式系统在遇到某节点或网络故障的时候,仍然能够对外提供满足一致性和可用性的服务。就是在网络中断的情况下,系统如果还能正常工作。

作为一个分布式系统,它和单机系统的最大区别,就在于网络.

现在假设一种极端情况,N1和N2之间的网络断开了:

假设N1和N2之间网络断开,由于网络是断开的,所以N2中的数据依旧是V0.

这时有用户向N2发送数据读取请求,

第一,牺牲数据一致性,保证可用性。响应旧的数据V0给用户;

第二,牺牲可用性,保证数据一致性。阻塞等待,直到网络连接恢复,数据更新操作M完成之后,再给用户响应最新的数据V1。

CA(一致性+可用性)without P(容错性)

单机的Mysql和Oracle;

分布式集群中不存在这种情况,因为多个节点必定考虑主备同步,也就是网络。

CP(一致性+容错性)without A(可用性)

分布式的数据库,如Redis,HBase,Zookeeper

任何时刻对ZooKeeper请求能得到一致的数据结果:当master节点网络故障,会进行选举机制,选举时集群不可用。但是它不能保证每次服务请求的可用性,ZooKeeper可能会丢弃一些请求,消费者程序需要重新请求才能获得结果。

AP(可用性+容错性)without C(一致性)

12306买票

购买的时候提示你是有票的(但是可能实际已经没票了),但是过了一会系统提示你下单失败,余票不足。其实舍弃的只是强一致性。退而求其次保证了最终一致性。

Eureka

各个节点平等;有节点挂掉,会立刻换至其他节点,保证服务可用,只不过查到的信息可能不是最新的。在网络稳定后,当前实例新的注册信息会被同步到其他节点中。

一旦网络问题发生,节点之间可能会失去联系。为了保证高可用,需要在用户访问时可以马上得到返回,导致全局数据的不一致性。

分布式一致性

分布式事务:指会涉及到操作多个数据库的事务。

关键在于保证在所有节点的数据写操作,要不全部都执行,要么全部的都不执行。但是一台机器在执行本地事务的时候无法知道其他机器中的本地事务的执行结果。所以也就不知道本次事务到底应该commit还是 roolback。

常规的解决办法就是引入一个“协调者”的组件来统一调度所有分布式节点的执行。

分布式事务处理模型:

应用程序( AP )、

事务管理器( TM )、常见的事务管理器是交易中间件

资源管理器( RM )、常见的资源管理器是数据库

通信资源管理器( CRM )常见的通信资源管理器是消息中间件

2PC(二阶段提交)

参与者(所有节点RM)将操作成败通知协调者(事务管理器TM),再由协调者根据所有参与者的反馈情报决定各参与者是否要提交操作还是中止操作。

第一阶段:准备阶段(投票阶段)

事务协调者(事务管理器)给每个参与者(资源管理器)发送Prepare消息,每个参与者要么直接返回失败(如权限验证失败),要么在本地执行事务,但不提交。

第二阶段:提交阶段(执行阶段)

如果协调者收到了参与者的失败消息或者超时,直接给每个参与者发送回滚(Rollback)消息;否则,发送提交(Commit)消息;参与者根据协调者的指令执行提交或者回滚操作,释放所有事务处理过程中使用的锁资源。

存在的问题:

1、同步阻塞问题。执行过程中,所有参与节点都是事务阻塞型的。当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态。

2、单点故障。由于协调者的重要性,一旦协调者发生故障。参与者会一直阻塞下去。尤其在第二阶段,协调者发生故障,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作。(如果是协调者挂掉,可以重新选举一个协调者,但是无法解决因为协调者宕机导致的参与者处于阻塞状态的问题)

3、数据不一致。在二阶段提交的阶段二中,当协调者向参与者发送commit请求之后,发生了局部网络异常或者在发送commit请求过程中协调者发生了故障,这回导致只有一部分参与者接受到了commit请求。而在这部分参与者接到commit请求之后就会执行commit操作。但是其他部分未接到commit请求的机器则无法执行事务提交。于是整个分布式系统便出现了数据部一致性的现象。

4、二阶段无法解决的问题:协调者再发出commit消息之后宕机,而唯一接收到这条消息的参与者同时也宕机了。那么即使协调者通过选举协议产生了新的协调者,这条事务的状态也是不确定的,没人知道事务是否被已经提交。

3PC(三阶段提交)

1、引入超时机制。同时在协调者和参与者中都引入超时机制。

2、把准备阶段一分为二,最终:canCommit,preCommit,DoCommit。

解决:1.单点故障问题,2.减少阻塞。

一旦参与者无法及时收到来自协调者的信息之后,会默认执行commit,而不会一直持有事务资源并处于阻塞状态。

存在问题:一致性问题。

由于网络原因,协调者发送的abort响应没有及时被参与者接收到,那么参与者在等待超时之后执行了commit操作。这样就和其他接到abort命令并执行回滚的参与者之间存在数据不一致的情况。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20191025A0DNLC00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券