场景十:分布式数据管理问题 分布式事务和分库分表方法介绍与实践经验分享
目录
image.png分库分表
为什么分片
image.png分库分表策略
image.png-
按照指定字段区间,按照查询维度来,尽量使得查询落在单库单表上,如时间段、ID段、区域等
-
按指定维度取模
image.png -
一致性哈希进行分片
image.png
环形Hash 空间
image.png
把数据通过一定的Hash算法处理后映射到环上
image.png
机器的添加
image.png
机器的删除
image.png
平衡性
image.png
平衡性- 虚拟节点
image.png
映射关系
相对均衡
image.png
进一步优化均衡
二次Hash,把负载大的节点再拆分后,对Hash值再进行二次Hash对应到拆分后的表上
image.png
分布式事务五种方法
为服务中数据存储层一致性如何做到?
五种分布式事务解决方案,按出现时间顺序进行讲解
两阶段提交 2PC
-
例子
image.png -
2PC流程
image.png
应用场景相对较少了,主要超时机制影响体验
TCC操作
image.png-
例子
image.png
总结
- 复杂场景下不推荐使用,逆向逻辑很复杂
-
只有非常简单的场景,非常容易提供回滚时使用
image.png
本地消息表
来源于早一代的支付公司,如ebay、支付宝。
设计思想:将远程分布式事务拆分成一系列的本地事务
转账例子
-
本地插入消息表
image.png -
本地消息表
通过本地事务绕过远程事务
image.png
第二步执行失败怎么处理?
再次重试,直到加成功为止,比如数据库故障导致的临时不成功。真实场景下第一步回滚很困难
业务导致的失败,比如对方账户销户,这需要通过一定的业务机制结合人工进行处理。
有些情况不一定在系统中实现,比如流单,有时可以从业务上解决比如赠送优惠券进行用户补偿等。
-
总结
比较经典的解决方案,依赖关系型数据库,存在吞吐量和性能方面的瓶颈
image.png
MQ非事务消息
- 示例 伪代码
public void trans(){
try{
//1.操作数据库
bool result= dao.update(model);//操作数据库失败,会抛出异常
//2.如果第一步成功,则操作消息队列投递消息
}catch(Exception ex){
}
}
image.png
-
总结
缺点:MQ的可靠性,消息延迟、挤压、丢失
做到幂等性避免消息重复消费
image.png
MQ事务消息
新出现的解决方案
本地成功后修改消息状态为可投递
image.png
-
总结
2018年主流开源MQ都没有实现对事务消息的支持
2019年RocketMQ等开源出来了事务性消息,虽然社区比较活跃,但建议核心流程暂时先不要使用事务型MQ。非核心业务可以尝试。
image.png
分布式事务的最佳实践
image.png本章小结
- 分库分表的常用手段:指定字段区间、按指定维度取模、一致性哈希进行分片
- 介绍分布式事务的五种方法:两阶段提交、TCC、本地消息表、MQ(非事务)、MQ(事务)
- 分布式事务的最佳实践介绍