分区取模分库分表策略:多表事务分库内闭环解决方案

简介: 当表数据超过一定量级,就需要通过分表来解决单表的性能瓶颈问题;当数据库负载超过一定水平线,就需要通过分库来解决单库的连接数、性能负载的瓶颈问题。本文将阐述在不同情况下,让不同数量级表,在同一个业务ID的事务操作路由到同一分库中的方案,省去解决垮库事务的烦恼。

image.png

作者 | 雨庄
来源 | 阿里技术公众号

一 前言

技术同学都知道,当表数据超过一定量级,我们就需要通过分表来解决单表的性能瓶颈问题;当数据库负载超过一定水平线,我们就需要通过分库来解决单库的连接数、性能负载的瓶颈问题。

本文主要阐述在同时满足以下业务场景:

  • 分表分库存储
  • 需要对分表数量不同的表进行同事务操作
  • 这些表的分库分表策略依赖的Sharding业务ID一致

等情况下,让这些不同数量级表,在同一个业务ID的事务操作路由到同一分库中的方案,省去解决垮库事务的烦恼。

二 案例

1 背景

假设有2个数据库实例,需要保存商家订单明细和汇总2张表的数据,这2张表的 分库分表策略都用shop_id取模策略,按单表数据500w的原则进行分表分库:

(1)shop_order_detail 商家订单明细表,日均数据6000w

image.png

(2)shop_order_stat 商家订单统计表,日均数据2000w

image.png

配置完成后生成的库表:

image.png

然后我们要做这么一件事情:在同一个事务中,新增用户订单明细成功后,更新用户订单统计数据:

image.png

2 问题

此时,我要处理一笔 user_id = 3 的订单数据:

image.png

如图,执行新增shop_order_detail表操作的时候,操作被路由到了DB0中;执行更新shop_order_stat表操作的时候,操作被路由到了DB1。这时候 这两个操作跨库了,无法在同一个事务中执行, 流程异常中断。

如果用TDDL组件的话就会报这样的错:

### Cause: ERR-CODE: [TDDL-4603][ERR_ACCROSS_DB_TRANSACTION] Transaction accross db is not supported in current transaction policy

三 解决方案

解决多表跨库事务的方案有很多,本文阐述的是如下解决方案:

将shop_order_stat作为shop_order_detail的映射基础表,调整shop_order_detail的分表策略,让shop_order_detail和shop_order_stat的数据都路由到同一个库中。

但该方案的前提是目标表的表数量是映射基础表表数量的N倍数。比如shop_order_stat的总表数量是4,shop_order_detail的总表数量是12,故shop_order_detail的总表数是shop_order_stat总表数的3倍。

shop_order_detail新分表分库策略的推导思路如下:

1 调整分库策略

首先,我们看shop_id在0~11范围内,用shop_id % 4分库分表策略shop_order_stat的sharding分布图:

image.png

用shop_id % 12分库分表策略shop_order_detail的sharding分布图:

image.png

图中看出,两张表都是根据shop_id做sharding,但现有同一个shop_id有可能会被路由到不同的库中,导致跨库操作。

此时,我只需要把shop_order_detail的分库策略调整为跟shop_order_stat一致,保证同一个shop_id能路由到同一个DB分片中就能解决这个问题。调整后的sharding分布图:

image.png

但调整完分库策略后,原本的表映射策略就失效了:

image.png

原本的shop_id = 5数据可以通过shop % 12 = 5的取模策略映射到DB0的shop_order_detail_05表上。调整完分库策略后,shop_id = 9被路由到了DB0中,通过shop % 12 = 9的取模策略会映射到shop_order_detail_09这张表上,但shop_order_detail_09这张表不在DB0中,所以操作失败了。

这时候,我们需要调整分表策略,把shop_id = 9的数据既映射到DB0中的shop_order_detail_05表中。

2 分区取模策略

首先,以shop_order_stat的单库表数量2作为分块大小,总表数量4作为分区大小,对shop_id=[0~11]进行分区操作,并且将shop_id根据分块大小取模:

image.png

当前分库数量为2,shop_order_stat的单库表数量为6,计算出跨库步长=分库下标*单库表数量:

image.png

根据分区下标和分块大小,计算出分区步长=分区下标*分块大小,最后根据分块取模数+跨库步长+分区步长就能定位到最终的分表下标了:

image.png

这样就完成了把shop_id = 9的数据既映射到DB0中的shop_order_detail_05表中的工作。

四 计算公式

分表下标路由策略计算公式:

分表下标 = 业务ID取模 % 分块大小 + 业务ID取模 / 分块大小 单库表数量 + 业务ID取模 / 分区大小 分块大小
  • 业务ID取模 = 业务ID % 总表数量
  • 分区大小 = 目标映射表的总表数量
  • 分块大小 = 目标映射表的单库表数量

以上面的案例为例,调整shop_order_detail的分库分表路由策略:

(1)shop_order_stat 商家订单统计表

image.png

(2)shop_order_detail 商家订单明细表

image.png

TDDL sharding-rule配置代码示例:

image.png

Java代码示例:

long shopId = 9;
int dbs = 2;
int tables = 12;
int oneDbTables = 6;
int partitionSize = 4;
int blockSize = 2;
int sharding = (int) (shopId % tables);
// 目标分库
int dbIndex = (int) (shopId % partitionSize / dbs);
// 目标分表
int tableIndex = sharding % blockSize + sharding % partitionSize / blockSize * oneDbTables + sharding / partitionSize * blockSize;

五 结尾

我是本地生活外卖商家运营研发团队中的一员,在实际业务场景的设计中遇到了多表事务分库内闭环的问题,没有找到适合的案例参考,才孵化出这个解决方案。

目前该方案已经在落地上线,有相同业务场景需求的同学可直接套用计算公式既可,欢迎大家交流沟通。


免费领取电子书

《阿里巴巴大数据及 AI 实战》

本书将深度剖析淘宝、高德、友盟+、1688、优酷、阿里妈妈、阿里影业大数据实战场景,是 2020 不容错过的企业大数据实战手册。

扫码加阿里妹好友,回复“阿里ai”获取吧~(英文字母小写,若扫码无效,可直接添加alimei4、alimei5、alimei6、alimei7)

image.png

相关文章
|
数据库 索引
深入理解数据库索引技术:回表与索引下推详解
【10月更文挑战第23天】 在数据库查询性能优化中,索引的使用是提升查询效率的关键。然而,并非所有的索引都能直接加速查询。本文将深入探讨两个重要的数据库索引技术:回表和索引下推,解释它们的概念、工作原理以及对性能的影响。
479 3
什么叫高内聚,低耦合 超简单生活例子,让你一看就明白
本文通过生活化的例子解释了高内聚和低耦合的概念,强调了在编写代码时应该追求高内聚(相关功能紧密组合)和低耦合(功能间相互独立,减少相互影响),以提高代码质量和可维护性。
1141 0
|
9月前
|
机器学习/深度学习 人工智能 自然语言处理
TrajectoryCrafter:腾讯黑科技!单目视频运镜自由重构,4D生成效果媲美实拍
TrajectoryCrafter 是腾讯与香港中文大学联合推出的单目视频相机轨迹重定向技术,支持后期自由调整视频的相机位置和角度,生成高质量的新型轨迹视频,广泛应用于沉浸式娱乐、创意视频制作等领域。
275 12
|
存储 算法 中间件
每日 3000万订单的社区电商要如何分库分表
文章首先介绍了分库分表的基本概念,包括分库、分表及其组合形式,并详细解释了水平切分、垂直切分和混合切分的方式。接着分析了分库分表的原因,如解决性能瓶颈、微服务化需求等。文章还讨论了分库分表的常见问题,如调试难度、分布式事务和跨库查询等,并介绍了分库分表工具的客户端模式和代理模式。最后,通过一个社区电商的真实案例,详细展示了分库分表的具体落地过程,包括评估库表总数、选择分库分表字段等关键步骤。
438 5
|
JavaScript
基于Vue2超简单实现DIY定制的步骤条
这篇文章介绍了如何在Vue 2中实现一个自定义设计的步骤条组件,包括子组件的设计和在父页面中的使用示例。
410 1
基于Vue2超简单实现DIY定制的步骤条
|
机器学习/深度学习 人工智能 算法
Stable Diffusion AI绘画
Stable Diffusion是人工智能领域的文本到图像生成模型,基于概率的连续扩散过程,学习数据潜在分布并生成新样本。模型使用Web UI进行交互,提供不同采样器如Euler和DPM++,后者常配以Karras算法。提示词对生成效果至关重要,可以利用GPT等生成提示词。用户还能调整参数如高清修复和批处理次数来影响生成的图像。此外,模型文件(ckpt/safetensors)和Lora微调模型需存放在正确目录以确保功能正常。
|
存储 Linux iOS开发
iOS 技术博主指南:填写苹果应用上架中的隐私政策信息
iOS 技术博主指南:填写苹果应用上架中的隐私政策信息
|
Linux 虚拟化
VMware虚拟机安装Linux教程(超详细) 1
VMware虚拟机安装Linux教程(超详细)
2544 0
|
存储 芯片 异构计算
FPGA-xilinx系列芯片的复位,你真的明白吗?(一)
FPGA-xilinx系列芯片的复位,你真的明白吗?
986 0
FPGA-xilinx系列芯片的复位,你真的明白吗?(一)
|
SQL 存储 Java
Spring 加强版 ORM 框架 spring-data-jdbc 入门与实践
前言 Spring 为了支持以统一的方式访问不同类型的数据库,提供了一个 Spring Data 框架,这个框架根据不同的数据库访问技术划分了不同的模块。上篇 《Spring 加强版 ORM 框架 Spring Data 入门》 介绍了不同模块遵循的通用规范,这篇我们来介绍下基于 JDBC 技术实现的 spring-data-jdbc 模块。
2295 0
Spring 加强版 ORM 框架 spring-data-jdbc 入门与实践