分布式事务
分布式事务
分布式事务的概念
分布式事务指的是一个请求在多个系统的调用链当中如何确保数据一致。
分布式事务协议
分布式事务协议:
- 2PC
- 3PC
- TCC
2PC 两阶段提交协议
2PC是非常经典的强一致、中心化的原子提交协议,协议中定义了两类节点:一个中心化协调者节点和多个参与者节点。2PC分为两个阶段:
准备阶段:
- 协调者向所有参与者发送事务内容,询问是否可以提交事务,并等待所有参与者答复;
- 各参与者执行事务操作,将Undo和Redo信息记入事务日志中(但不提交事务);
- 如参与者执行成功,给协调者反馈YES,即可以提交;如执行失败,给协调者反馈NO,即不可提交。
提交阶段(所有参与者均反馈YES):
- 协调者向所有参与者发出正式提交事务的请求(即Commit请求);
- 参与者执行Commit请求,并释放整个事务期间占用的资源;
- 各参与者向协调者反馈Ack完成的消息;
- 协调者收到所有参与者反馈的Ack消息后,即完成事务提交。
提交阶段(任何一个参与者反馈NO):
- 协调者向所有参与者发出回滚请求(即Rollback请求);
- 参与者使用阶段1中的Undo信息执行回滚操作,并释放整个事务期间占用的资源;
- 各参与者向协调者反馈Ack完成的消息;
- 协调者收到所有参与者反馈的Ack消息后,即完成事务中断。
2PC两阶段提交过程中会遇到一些问题:
- 性能问题:从流程上可以看出,其最大缺点就在于它的执行过程中间,节点都处于阻塞状态。各个操作数据库的节点此时都占用着数据库资源,只有当所有节点准备完毕,事务协调者才会通知进行全局提交,参与者进行本地事务提交后才会释放资源。
- 协调者单点故障问题:事务协调者是整个XA模型的核心,一旦事务协调者节点挂掉,会导致参与者收不到提交或回滚的通知,从而导致参与者节点始终处于事务无法完成的中间状态。
- 丢失消息导致的数据不一致问题:在第二个阶段,如果发生局部网络问题,一部分事务参与者收到了提交消息,另一部分事务参与者没收到提交消息,那么就会导致节点间数据的不一致问题。
3PC三阶段提交协议
2PC的改进版本,其在两阶段提交的基础上增加了CanCommit阶段,并引入了超时机制。一旦事务参与者迟迟没有收到协调者的Commit请求,就会自动进行本地commit,这样相对有效地解决了协调者单点故障的问题。
阶段1:CanCommit
- 协调者向所有参与者发出包含事务内容的CanCommit请求,询问是否可以提交事务,并等待所有参与者答复;
- 参与者收到CanCommit请求后,如果认为可以执行事务操作,则反馈YES并进入预备状态,否则反馈NO。
阶段2:PreCommit 事务预提交:(所有参与者均反馈YES时)
- 协调者向所有参与者发出PreCommit请求,进入准备阶段;
- 参与者收到PreCommit请求后,执行事务操作,将Undo和Redo信息记入事务日志中(但不提交事务);
- 各参与者向协调者反馈Ack响应或No响应,并等待最终指令。
阶段2:PreCommit :中断事务(任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈时)
- 协调者向所有参与者发出abort请求;
- 无论收到协调者发出的abort请求,或在等待协调者请求过程中出现超时,参与者均会中断事务。
阶段3:do Commit 提交事务:(所有参与者均反馈Ack响应时)
- 如果协调者处于工作状态,则向所有参与者发出do Commit请求;
- 参与者收到do Commit请求后,会正式执行事务提交,并释放整个事务期间占用的资源;
- 各参与者向协调者反馈Ack完成的消息;
- 协调者收到所有参与者反馈的Ack消息后,即完成事务提交。
阶段3:do Commit 中断事务:(任何一个参与者反馈NO,或者等待超时后协调者尚无法收到所有参与者的反馈时)
- 如果协调者处于工作状态,向所有参与者发出abort请求;
- 参与者使用阶段1中的Undo信息执行回滚操作,并释放整个事务期间占用的资源;
- 各参与者向协调者反馈Ack完成的消息;
- 协调者收到所有参与者反馈的Ack消息后,即完成事务中断。
TCC 补偿事务协议
TCC 将事务提交分为 Try - Confirm - Cancel 3个操作:
- Try:预留业务资源/数据效验
- Confirm:确认执行业务操作
- Cancel:取消执行业务操作
TCC事务处理流程和 2PC 二阶段提交类似,不过 2PC通常都是在跨库的DB层面,而TCC本质就是一个应用层面的2PC。
CAP原则
概念
CAP原则又称CAP定理,指的是在一个分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。CAP 原则指的是,这三个要素最多只能同时实现两点,不可能三者兼顾。
- 一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。(等同于所有节点访问同一份最新的数据副本)
- 可用性(A):保证每个请求不管成功或者失败都有响应。
- 分区容忍性(P):系统中任意信息的丢失或失败不会影响系统的继续运作。
CAP特性的取舍
- 满足CA舍弃P,也就是满足一致性和可用性,舍弃容错性。但是这也就意味着你的系统不是分布式的了,因为涉及分布式的想法就是把功能分开,部署到不同的机器上。
- 满足CP舍弃A,也就是满足一致性和容错性,舍弃可用性。如果你的系统允许有段时间的访问失效等问题,这个是可以满足的。就好比多个人并发买票,后台网络出现故障,你买的时候系统就崩溃了。
- 满足AP舍弃C,也就是满足可用性和容错性,舍弃一致性。这也就是意味着你的系统在并发访问的时候可能会出现数据不一致的情况。
实时证明,大多数都是牺牲了一致性。像12306还有淘宝网,就好比是你买火车票,本来你看到的是还有一张票,其实在这个时刻已经被买走了,你填好了信息准备买的时候发现系统提示你没票了。这就是牺牲了一致性。
但是不是说牺牲一致性一定是最好的。就好比mysql中的事务机制,张三给李四转了100块钱,这时候必须保证张三的账户上少了100,李四的账户多了100。因此需要数据的一致性,而且什么时候转钱都可以,也需要可用性。但是可以转钱失败是可以允许的。