案例:浅谈订单系统分库分表设计

概述

订单是电商系统中核心业务对象,随着业务发展,订单量激增,其性能问题逐渐凸现。

为解决性能问题,可以采用读写分离、加缓存等方式,当数据量达到千万级别,原先的解决方案,瓶颈凸现,需要进行分库分表的架构改造。解决高并发写,海量存储的问题。

订单模型

Order,OrderItem,收货信息,优惠信息,退款单

容量预估

现有容量:每天10万单,一月300万,一年3600万。

预估(3~5年)容量:每天100万单,一月3000万,一年36000万(3.6亿)

按照目前的发展,性能很快会遇到性能瓶颈。

分片设计

因为订单系统主要的使用者是用户(顾客),商家、运营人员。使用最大的角色是用户,所以优先从用户的角度进行拆分,保障用户的使用体验。

1、我们采用的分片规则是用户Id和订单号。我们按照16个库*32张表设计,可以满足未来每年3.6亿订单的需求,我们先按照8*16设计,当数据量上来后,再进行一次扩容。

2、用户Id用于路由到哪个库,订单号用于路由到那个表。

3、订单号采用基因法,包含用户Id后三位,便于用订单号查询时,定位分库。

异构设计

分库分表采用用户维度进行设计,当商家或运营人员查询的时候,需要查询所有库表进行数据聚合。对于在线业务,性能是不可容忍的。所以需要进行异构设计。

针对商家维度,可以进行异构,以商家Id进行分库,以订单Id进行分表。

针对运营人员:可以将需要异构到Elasticsearch、Tidb或Hbase中进行查询。

常见问题

JOIN查询

(1)采用ER表(绑定表)的方式,与订单相关的表同样规则进行拆分,可以进行关联查询。

(2)字典类数据量小的表,采用广播表的方式,同步数据到所有库中,直接关联查询。

主键Id:采用分布式ID方式,比如雪花分片。

分布式事务:采用ER表、方式尽量避免分布式事务,如果需要则可以引入Seata等分布式事务方案。

组件技术选型:Sharding Jdbc【ShardingSphere】

数据迁移

迁移通常采用:双写+对数对比的方式,不停机实现。

(1)同步双写:(或异步:Canel,MQ等)

(2)老数据迁移:启用离线任务,将老数据批量迁移到新库。

(3)数据校验:校验新、老库数据是否一致。

(4)灰度校验:

a、先切少量读流量,观察日志、延迟等,再逐步放开大流量。

b、开放少量写流量,同上。

(5)全量切换到新的分库分表逻辑。