1 业务背景
F6 汽车科技,是一家专注于汽车后市场信息化建设的互联网平台公司,为维修企业开发智慧管理平台。各个维修企业(后文简称商户)之间的数据是相互隔离的,不同商户之间的数据理论上可以存储在不同库不同表。随着公司业务发展迅速,有些表的数据量增长迅速,单表总的数据量达到千万甚至亿的级别,系统越来越难以满足业务的高速发展。另外随着业务发展公司也在对系统进行拆分,按照不同域不同业务拆分成许多微服务,随之也就垂直拆分成了不同的业务库。
2 技术背景
关系型数据库由于单机存储容量、连接数、处理能力都有限,容易成为系统瓶颈。从性能上看,当单表的数据量达到千万以后,由于查询维度较多,即使添加从库、优化索引,做很多操作时性能仍下降严重。此时就要考虑对其进行切分了,切分的目的就在于减少数据库的负担,缩短查询时间。另外单库的连接数有限,如果数据库查询的 QPS 过高,那么就需要通过分库来分担单个数据库的连接压力。从可用性上看,单个数据库如果发生意外,很可能会丢失所有数据,影响所有业务,分库可以隔离故障,减少业务的影响范围。通常,表的体积大于 2G 或者行数大于 1000w,并且数据快速增长,这个时候就要考虑进行分库分表。
3 分库分表介绍
根据业界经验,分库分表有以下四种常见形式:
- 垂直分表——大表拆小表,基于字段进行,将一些不常使用或长度较大字段拆分成扩展表;
- 垂直分库——基于业务边界进行数据库层面的拆分,解决单库的性能瓶颈;
- 水平分表——横向分表,将表中的数据行按照一定规律分布到不同的表中,降低单表数据量,优化查询性能,但是库级别还存在瓶颈;
- 水平分库分表——在水平分表基础上,将数据进一步分布到不同的库中,有效缓解单机和单库的性能瓶颈和压力,突破 IO、连接数、硬件资源的瓶颈;
业界常用的分库分表解决方案
1、Sharding-JDBC (ShardingSphere)
优点:
- 社区活跃,目前已经升级至 5.0 版本,仍处于快速迭代中;
- 成功应用案例多,京东、当当等大公司广泛应用;
- 使用简单,Sharding-JDBC 快速集成项目,不需要部署额外服务;
- 兼容性好,路由至单数据节点,SQL 100% 支持;
- 性能优异,损耗低,官网有测试结果。
缺点:
- 增加运维成本,分表后修改字段,增加索引繁琐——可以部署 Sharding-Proxy 解决,支持异构语言,对运维友好;
- 尚未支持分片数据动态迁移,需要开发功能实现。
2、MyCat
优点:
- MyCat 是介于应用与数据库之间,进行数据处理与交互的中间服务,对研发无感知,接入成本低
- 支持 JDBC 连接 ORACLE、DB2、SQL Server、MYSQL 等数据库
- 支持多语言、跨平台,部署和实施简单
- 高可用,故障自动切换
缺点:
- 运维成本高,得配置 Mycat 的一系列参数以及高可用负载均衡的配置
- 需要单独部署一个服务,增加了系统风险
其他类似的解决方案如:Cobar、Zebra、MTDDL、tidb 就没有过多的去研究了,有兴趣的可以自己去研究下。结合公司实际情况我们选择了 ShardingSphere。
4 总体方案
按照公司现有业务逻辑,因此采用商户 ID 作为分片键(ShardingKey),保证一个商户的工单数据,分配在同一个库同一个单表中,避免了多表查询关联的性能损耗,后期分片到多个库时,可以避免跨库事务及跨库 JOIN。
商户 ID 数据库中的类型为 BIGINT(20),为了保证后续分库扩容的需求,采用基因法,选取商户 ID 最后两位作为分库基因,按照双倍扩容的规则,可以最大扩展到 64 个库中。剩余位数的值用于分表,分片到 32 个分表中。
规则如下(