背景
因业务高速发展,线下渠道订单量高速增长,订单量每天50w+,据此计算,一个月的订单量有1500w+,一年就有1.8亿数据。
这已远远超过MySQL单表的存储极限。故急需分表
技术方案
根据自己前几年调研过的技术方案,选择使用ShardingJDBC来实现
各方案优缺点不再此展示,感兴趣的可以自行探索
具体接入代码
我们的ORM工具使用的是mybatis-plus,并且结合了多数据源,所以这次接入是在该背景下接入sharding-jdbc。如果需要单独接入sharding-jdbc可以自己截取部分粘贴到自己项目
依赖:
yml配置:
Spring配置:
当且仅当需要使用分表时才需要切换数据源:
@DS(DataSourceConfiguration.SHARDING_DATA_SOURCE_NAME)
@DS
是dynamic-datasource-spring-boot-starter的注解,用于切换动态数据源
分表策略
因为线下渠道的用户有非会员和会员。所以我们的分表策略是,非会员按照年月归档,会员用户按照用户id分表。我们期望的是会员用户可以通过用户ID和订单号都可以定位到具体的分表,所以我们对自己内部订单号做了一些设计。
规则是: 雪花算法 + 用户ID(后3位)
通过此设计就可以达到通过用户ID和订单号都可以定位到具体分表
分表算法
因为我们的使用场景需要按年月归档非会员订单和按照用户维度进行分表,所以我们采用了灵活性非常之高的强制分片算法,实现HintShardingAlgorithm即可。
com.moatkon.MoatkonShardingHintAlgorithm
数据倾斜问题
主要是采用 Hash一致性算法 + 虚拟表 来解决。
为什么采用虚拟表?
避免数据倾斜问题,如果出现了数据倾斜问题,而又没有采用虚拟表,大概率会将所有的数据都重新跑一遍新的分表算法(这个新的分表算法如果还没有采用虚拟表,估计也只能支撑一段时间,并不能彻底解决问题),这个成本太大了
实现原理
算法实现
1024张虚拟表,128张物理表