背景
部门内有一些亿级别核心业务表增速非常快,增量日均100W,但线上业务只依赖近一周的数据。随着数据量的迅速增长,慢SQL频发,数据库性能下降,系统稳定性受到严重影响。本篇文章,将分享如何使用MyBatis拦截器低成本的提升数据库稳定性。
业界常见方案
针对冷数据多的大表,常用的策略有以2种:
1. 删除/归档旧数据。
2. 分表。
归档/删除旧数据
定期将冷数据移动到归档表或者冷存储中,或定期对表进行删除,以减少表的大小。此策略逻辑简单,只需要编写一个JOB定期执行SQL删除数据。我们开始也是用这种方案,但此方案也有一些副作用:
1.数据删除会影响数据库性能,引发慢sql,多张表并行删除,数据库压力会更大。
2.频繁删除数据,会产生数据库碎片,影响数据库性能,引发慢SQL。
综上,此方案有一定风险,为了规避这种风险,我们决定采用另一种方案:分表。
分表
我们决定按日期对表进行横向拆分,实现让系统每周生成一张周期表,表内只存近一周的数据,规避单表过大带来的风险。
分表方案选型
经调研,考虑2种分表方案:Sharding-JDBC、利用Mybatis自带的拦截器特性。
经过对比后,决定采用Mybatis拦截器来实现分表,原因如下:
1.JAVA生态中很常用的分表框架是Sharding-JDBC,虽然功能强大,但需要一定的接入成本,并且很多功能暂时用不上。
2.系统本身已经在使用Mybatis了,只需要添加一个mybaits拦截器,把SQL表名替换为新的周期表就可以了,没有接入新框架的成本,开发成本也不高。

分表具体实现代码
分表配置对象
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ShardingProperty {
// 分表周期天数,配置7,就是一周一分
private Integer days;
// 分表开始日期,需要用这个日期计算周期表名
private Date beginDate;
// 需要分表的表名
private String tableName;
}
分表配置类
import java.util.concurrent.ConcurrentHashMap;
public class ShardingPropertyConfig {
public static final ConcurrentHashMap<String, ShardingProperty> SHARDING_TABLE = new ConcurrentHashMap<>();
static {
ShardingProperty orderInfoShardingConfig = new ShardingProperty(15, DateUtils.string2Date("20231117"), "order_info");
ShardingProperty userInfoShardingConfig = new ShardingProperty(7, DateUtils.string2Date("20231117"), "user_info");
SHARDING_TABLE.put(orderInfoShardingConfig.getTableName(), orderInfoShardingConfig);
SHARDING_TABLE.put(userInfoShardingConfig.getTableName(), userInfoShardingConfig);
}
}
拦截器
import lombok.ex

最低0.47元/天 解锁文章
2258

被折叠的 条评论
为什么被折叠?



