一.概述
采用mod 2^n分库分表方法,本质上是一致性hash。
容量估计:
每个表按最大3000w存储,
64个库*64张表=1228.8亿
orderNo订单号设计:
15时间 + 5位ip + 5位自增序列 +3位随机数 + 4位分库分表数字。
库规则(订单最后2位):用户id/64%64;库规则虚拟空间范围:0-63
表规则(订单倒第3位和倒数第4位):用户id%64;表规则虚拟空间范围0-63
订单路由时,直接根据订单后4位进行以下计算:
最终物理库规则=库规则/当前库分组个数*每个分组库个数
最终物理表规则=表规则/当前表分组个数*每个分组表个数
图:
eg:
当前是2个物理库,2个物理分表。
则:
最终物理库规则=库规则/32*32
最终物理表规则=表规则/32*32
则库规则=01,表规则=01
最终物理库规则=01/32*32=0
最终物理表规则=01/32*32=0
则库规则=02,表规则=02
最终物理库规则=02/32*32=0
最终物理表规则=02/32*32=0
一直到库规则为31都会路由到0库0表。
则库规则>=32,表规则>=32
最终物理库规则=32/32*32=32
最终物理表规则=32/32*32=32
二.扩容
2个物理表, order_0000,order_0032
每个分组32个逻辑分表
原先元素分布:
逻辑分表号:0-31 在order_0000,32-63在order_0032
扩展成4个物理分表
每个逻辑分组有:16个逻辑分表
即 order_0000,order_0016,order_0032,order_0048
物理分表名=逻辑分表号/16*16
数据迁移:
order_0000中逻辑分表号:16-31的数据往order_0016迁
order_0032中,逻辑分表号:48-63的数据往order_0048迁
即只需迁移原先每个物理表一半的数据到新的物理表,二分裂变。
扩容的本质是物理表数增加,逻辑分组表数减少。
三.扩容具体过程
eg:
原先1个库,二个表,扩容成4个表。
原先物理表:
0000,0032
0000管理虚拟id范围为:0-31
0032管理虚拟id范围为:32-63
扩容后物理表:
0000,0016,0032,0048
停机方案具体流程:
优:切换快速,简单;缺:停机影响正常业务
0.准备好0016及0048两张新表。
1.对外停止交易,停止相应会引起订单状态变化的job
2.将0000表数据拷到0016,将0032拷到0048。
3.校验0016及0048中表数据与0000及0032的数据一致
从条数,明细等进行核对,相应订单明细记录状态都一致。
3.启用新的规则
根据用户id路由到表规则更改为:userId %64 /16 * 16 (原先:userId %32 /32 * 32)
根据订单号id路由到表规则更改为:取订单最后2位分表id / 16 * 16 (原先是/32 * 32)
这步做完后相应的查询流量已经变为新的查询。
4.开启交易,开启之前停掉的job
5.定时check数据,日志看是否有异常
6.找个时间点清除0000及0032中不用的数据
0000的虚拟id区间为:15-31的清掉
0032的虚拟id区间为:48-63的清掉
不停机方案具体流程:
优:不影响业务,对业务透明;缺:时间会拉长,方案复杂点
0.准备好0016及0048两张新表;检测脚本:总量,明细检查
1.历史数据同步
2.检查两边数据没问题,切换双写
0000数据新规则下的会双写到0016,0032到0048
3.观察数据检查,业务低峰值将读写切到新规则
此时0000表只落新规则下他要承接的数据,0016落新规则下他要承接的数据;0032及0048一样。
4.观察切换后,没问题一段时间,清掉0000,0016,0032,0048各自在新规则下不属于他们的记录