原文地址:https://mp.weixin.qq.com/s/qheAd1oUcQaWaZa_nF4OFg
今天读了匙凯明的《京东618实践:一元抢宝系统的数据库架构优化》,写一写感受。
京东618是一个耳熟能详的事件,一元抢宝系统是京东虚拟新兴的一个业务系统,上线以来订单量一直持续增长。在距离618前两个月时,京东商城商品虚拟研发部对系统做了整体预估,订单量快速增长及618大促的到来都将带来单量剧增,届时势必会对数据库容量和负载造成压力。
通过技术改造,从整体上来说实现三个目标:底层路由策略实现;历史数据迁移;业务改造。下面详细介绍本次改造的过程。
数据库容器预估:
分库分表最重要的是要先做容器预估,依据数据量和业务特性估算出容器/库/表的数量及分库分表规则。假设一天100万订单,一年则产生3.6亿订单量;假设数据结构是这样的:订单表10个字段,一个字段50个字符;一条订单则需要500字节存储,那么3.6亿订单则需要大约170GB存储空间;假设每台机器存储空间为200GB,则每年增加一台机器即可满足容量需求。而实际需求要根据压测结果来决定;如压测其他一些指标是否满足需求,如QPS、响应时间等。可以看到需求量确实是很大的,由此底层路由器选择了分区路由法
抢宝项是业务上层维度,可以理解为商品,大部分表中都有这个字段;此id生成时是连续的,长期来看,hash分库后数据是均衡的。抢宝期是抢宝项下的一个维度,如一个项库存是100,不停售前提下,会生成100期,在售的期次只有一个。
为什么选择期id区间作为分表路由策略呢,有朋友会认为也可以选择订单id,从路由策略上来说,没有问题,但一元抢宝项目的业务场景,有根据项id和期id查询订单参与纪录的场景,所以要考虑通过这两个维度能查到订单。另外,使用区间作为分表策略,可以动态扩展,即使每次查询经过路由表,这点开销可以忽略,而且都是通过缓存加载。
那以上策略,可以路由的维度有哪些呢?
通过订单id路由:订单号按照一定规则生成,其存储了库和表的信息,可以根据订单号直接定位到相应的库和表;通过抢宝项id和抢宝期id路由:抢宝项hash定位到库,抢宝期查询路由策略表定位到表,聚合查询及聚合数据同步、历史数据迁移、系统关键节点降级实现方式很巧妙。
最后总结
一个系统从设计到最终完成,依赖于整个团队,每个人的想法、不同思路的碰撞和付出;再有前期合理细致的设计尤为重要,每个时间点和具体上线步骤和回滚方案做好详细计划;另外,就是细致深入测试,测试环境和线上多轮测试和回归,也是正常上线的重要保证。