分布式事务及解决方案
定义:事务发起方执行完成本地事务后发送一条消息,事务参与方收到消息,并且一定能将消息消费,此方案强调的是消息发给参与方,最终达到一致
1.本地事务与消息发送的原子性(成功都成功,失败都失败)
2.事务参与方接受消息的可靠性
3.消息重复消费
2.分布式幂等如何设计
1、建立一个或一组唯一索引
2、使用悲观锁,for update,一般伴随事务一起使用,数据锁定时间可能会很长。另外需要考虑where条件里是否为主键,如果不是,则会锁全表
3、乐观锁,给表加一个version字段,通过这个字段判断数据是否被修改
4、分布式锁,利用redis、zookeeper等放入一个字符串,并设置失效时间
3.ACID、CAP、BASE理论
ACID:指数据库事务正确执行的四个条件
A:原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
C:一致性(Consistency):指的是操作前后,总数据保持保持不变。(-100块与+100块)
I:隔离性(Isolation)**:多个事务并发执行时,一个事务的执行不应影响其他事务的执行。张三取钱不会影响李四取钱。
D:持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。在事务结束时,此操作将不可逆转。
CAP:CAP定理,又被叫作布鲁尔定理。
C:一致性
对于数据分布在不同节点上的数据来说,如果在某个节点更新了数据,那么在其他节点如果都能读取到这个最新的数据,那么就称为强一致,如果有某个节点没有读取到,那就是分布式不一致。
A:可用性
非故障的节点在合理的时间内返回合理的响应(不是错误和超时的响应)。可用性的两个关键一个是合理的时间,一个是合理的响应。
P:分区容错性
当出现网络分区后,系统能够继续工作。打个比方,这里集群有多台机器,有台机器网络出现了问题,但是这个集群仍然可以正常工作。
CAP理论认为,这三个条件只能同时满足其中两个,不能同时满足三个;
分布式系统理论上不可能选择 CA 架构,只能选择 CP 或者 AP 架构。
BASE理论:基于CAP理论,BASE理论认为系统基本可用,数据最终保持就可以了(允许数据可以短暂不一致)。
4.分布式事务模型
单个服务,多个数据库,是分布式事务;
多个应用,多个数据库也是分布式事务;
多个应用,调用其他的应用,再加上多个数据库也是分布式事务(微服务中的典型模型);
5.分布式事务的解决方案
1.两阶段提交(2PC)
-
第一阶段(准备阶段):事务协调者向所有参与者发送准备请求,每个参与者预执行操作并锁定资源,但不提交。
-
第二阶段(提交阶段):如果所有参与者都准备好,协调者发送提交请求;如果有任何一个参与者失败,协调者发送回滚请求。
举例:基于XA协议的两阶段提交:
假设数据库1控制库存,数据库2控制积分,数据库3控制日志;TransactionManagement为统一事务管理器
第一个阶段:
数据库1执行库存扣减操作,但是不提交----->汇报操作成功与否给TransactionManagement
数据库2执行积分增加操作,但是不提交----->汇报操作成功与否给TransactionManagement
数据库3执行记录日志操作,但是不提交----->汇报操作成功与否给TransactionManagement
第二个阶段:
TransactionManagement确认以上三个操作都成功了,然后通知三个数据库进行提交操作;
若是以上三个操作有一个失败了,则进行回滚操作;
优点:尽量保证了数据的强一致,适合对数据强一致要求很高的关键领域。
缺点:牺牲了可用性,对性能影响较大,不适合高并发高性能场景,如果分布式系统跨接口调用,目前 .NET 界还没有实现方案。
2.三阶段提交(3PC)
-
第一阶段(准备阶段):与2PC相同。
-
第二阶段(预提交阶段):所有参与者收到预提交请求后,将事务写入日志,但不提交。
-
第三阶段(提交阶段):如果所有参与者都成功预提交,协调者发送提交请求;否则发送回滚请求。
3.最终消息一致性
-
使用消息队列来协调事务,通过发布和订阅机制确保所有参与者都能接收到事务的状态变化。
-
参与者根据接收到的消息进行相应的操作,并通过心跳检测等机制来处理网络分区和故障恢复。
4.TCC模式
2PC 和 3PC 都是数据库层面的,而 TCC 是业务层面的分布式事务
补偿事务(TCC)
TCC 将事务提交分为 Try(method1) - Confirm(method2) - Cancel(method3) 3个操作。
其和两阶段提交有点类似,Try为第一阶段,Confirm - Cancel为第二阶段,是一种应用层面侵入业务的两阶段提交。
Try:在这个阶段,先对数据进行备份,然后执行业务,提交事务,通知事务管理器操作成功与否;
Confirm:在这个阶段,事务管理器确认对各个数据库的操作是否有异常,无异常则confirm并更改干掉备份数据,有异常则进入cancel
Cancel:若有数据库操作失败,则执行代码,将原先的备份数据还原;
优点: 跟2PC比起来,实现以及流程相对简单了一些,但数据的一致性比2PC也要差一些
缺点:缺点还是比较明显的,在2,3步中都有可能失败。TCC属于应用层的一种补偿方式,
所以需要程序员在实现的时候多写很多补偿的代码,在一些场景中,一些业务流程可能用TCC不太好定义及处理。
4.本地消息表:本地创建消息日志表,定时扫描日志表,批量发送消息
5.消息事务
6.最大努力通知
总结
可以看出 2PC 和 3PC 是一种强一致性事务,不过还是有数据不一致,阻塞等风险,而且只能用在数据库层面。
而 TCC 是一种补偿性事务思想,适用的范围更广,在业务层面实现,因此对业务的侵入性较大,每一个操作都需要实现对应的三个方法。
本地消息、事务消息和最大努力通知其实都是最终一致性事务,因此适用于一些对时间不敏感的业务。
5.Saga模式
-
将长事务分解为一系列小事务,每个小事务都有一个对应的补偿操作。
-
如果某个小事务失败,系统会执行一系列补偿操作来回滚之前的操作。
RocketMq事务消息方案
6.TCC事务需要注意的问题
幂等、悬挂、空回滚
1、空回滚:在没有调用try的情况下,直接调用了cancle,cancle需要识别出这是一个空回滚,并返回成功
2、悬挂:对于一个分布式事务,二阶段cancle接口比try接口先执行
3、幂等:每个阶段无论执行多少次,结果都因该相同
7.TCC事务优缺点
TCC事务优点
1、可以让应用自定义操作力度
2、降低锁冲突
3、提高吞吐量
TCC事务缺点:
1、代价较高,需要写三个阶段的方法
2、业务耦合度高,增加开发成本
8.常见的负载均衡算法
1、轮询
2、加权轮询
3、随机
4、最少连接
5、源地址hash
9.常见的限流算法
1、计数器算法(固定窗口)
在固定周期内累加访问次数,超过阈值则限流。缺点在于如果限流周期较长则失效(比如上一个周期的最后几秒和下一个周期的开始几秒加起来到达阈值)
2、滑动窗口
将时间周期分为N个小周期,分别记录每个小周期的访问次数,并且根据滑动时间删除过期的小周期
3、漏桶算法
请求到达时直接放入漏桶,如果已经到达容量上限,则触发限流策略。漏桶以固定的速率释放请求
4、令牌桶算法
以r(r=时间周期/限流值)的速度向桶中增加令牌,直到令牌桶满,请求到达时向桶请求令牌,拿到令牌则通过,拿不到则触发限流策略
10.数据库如何处理海量数据
分库分表、主从架构、读写分离
12.redis令牌桶实现方案
-
令牌生成:系统按照设定的速率(如每秒N个)向桶中添加令牌,直到桶满为止。桶的容量是有限的,代表了系统在短期内能够处理的最大请求量。
-
请求处理:每当有请求到达时,系统会尝试从桶中取出一个令牌。如果桶中有令牌,请求就被处理并消耗掉一个令牌;如果桶中没有令牌,请求则被拒绝或等待。
-
灵活控制:通过调整令牌的生成速率和桶的容量,可以灵活地控制数据传输的平均速率和允许的突发速率。
-