食品网站应该怎么做,wordpress 中文cms模版,中国住房和城乡建设网站,上海网站建设推荐秒搜科技简介#xff1a; 当表数据超过一定量级#xff0c;就需要通过分表来解决单表的性能瓶颈问题#xff1b;当数据库负载超过一定水平线#xff0c;就需要通过分库来解决单库的连接数、性能负载的瓶颈问题。本文将阐述在不同情况下#xff0c;让不同数量级表#xff0c;在同一…简介 当表数据超过一定量级就需要通过分表来解决单表的性能瓶颈问题当数据库负载超过一定水平线就需要通过分库来解决单库的连接数、性能负载的瓶颈问题。本文将阐述在不同情况下让不同数量级表在同一个业务ID的事务操作路由到同一分库中的方案省去解决垮库事务的烦恼。 作者 | 雨庄 来源 | 阿里技术公众号
一 前言
技术同学都知道当表数据超过一定量级我们就需要通过分表来解决单表的性能瓶颈问题当数据库负载超过一定水平线我们就需要通过分库来解决单库的连接数、性能负载的瓶颈问题。
本文主要阐述在同时满足以下业务场景
分表分库存储需要对分表数量不同的表进行同事务操作这些表的分库分表策略依赖的Sharding业务ID一致
等情况下让这些不同数量级表在同一个业务ID的事务操作路由到同一分库中的方案省去解决垮库事务的烦恼。
二 案例
1 背景
假设有2个数据库实例需要保存商家订单明细和汇总2张表的数据这2张表的 分库分表策略都用shop_id取模策略按单表数据500w的原则进行分表分库
1shop_order_detail 商家订单明细表日均数据6000w 2shop_order_stat 商家订单统计表日均数据2000w 配置完成后生成的库表 然后我们要做这么一件事情在同一个事务中新增用户订单明细成功后更新用户订单统计数据 2 问题
此时我要处理一笔 user_id 3 的订单数据 如图执行新增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的总表数量是4shop_order_detail的总表数量是12故shop_order_detail的总表数是shop_order_stat总表数的3倍。
shop_order_detail新分表分库策略的推导思路如下
1 调整分库策略
首先我们看shop_id在011范围内用shop_id % 4分库分表策略shop_order_stat的sharding分布图 用shop_id % 12分库分表策略shop_order_detail的sharding分布图 图中看出两张表都是根据shop_id做sharding但现有同一个shop_id有可能会被路由到不同的库中导致跨库操作。
此时我只需要把shop_order_detail的分库策略调整为跟shop_order_stat一致保证同一个shop_id能路由到同一个DB分片中就能解决这个问题。调整后的sharding分布图 但调整完分库策略后原本的表映射策略就失效了 原本的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根据分块大小取模 当前分库数量为2shop_order_stat的单库表数量为6计算出跨库步长分库下标*单库表数量 根据分区下标和分块大小计算出分区步长分区下标*分块大小最后根据分块取模数跨库步长分区步长就能定位到最终的分表下标了 这样就完成了把shop_id 9的数据既映射到DB0中的shop_order_detail_05表中的工作。
四 计算公式
分表下标路由策略计算公式
分表下标 业务ID取模 % 分块大小 业务ID取模 / 分块大小 单库表数量 业务ID取模 / 分区大小 分块大小业务ID取模 业务ID % 总表数量分区大小 目标映射表的总表数量分块大小 目标映射表的单库表数量
以上面的案例为例调整shop_order_detail的分库分表路由策略
1shop_order_stat 商家订单统计表 2shop_order_detail 商家订单明细表 TDDL sharding-rule配置代码示例 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;
五 结尾
我是本地生活外卖商家运营研发团队中的一员在实际业务场景的设计中遇到了多表事务分库内闭环的问题没有找到适合的案例参考才孵化出这个解决方案。
目前该方案已经在落地上线有相同业务场景需求的同学可直接套用计算公式既可欢迎大家交流沟通。
原文链接
本文为阿里云原创内容未经允许不得转载。