分库分表实践

 

 

一、项目背景

今年我们架构组主导的主要任务之一就是组织会员系统的分库分表操作,经过上半年的立项、改造、测试、联调、验收、演练,终于完成上线,会员系统是一个基础微服务,经过两年多的运行,目前已为很多系统提供基础服务,现在已不能进行停机升级操作,于是我们确定了不停机升级方案,经过演练最终上线完成。

二、分库分表实施

1.  现有数据库表梳理

按场景对会员库数据量大于1000万的表进行了梳理,根据不同表的使用情况进行了分析,根据分析的情况将大表的数据分两种处理方式,

  • 一种是将表数据定期归档,这种情况不在此次讨论范围内;
  • 另一种是进行分库分表操作。

会员库数据大表包括三种,

  • 一种是历史数据归档表,这种表只是数据的归档存储,这类型表不需要分库分表;
  • 一种是以前业务临时使用,现在已不使用的表,这部分表也不需要分库分表;
  • 最后一种核心表,需要根据场景进行分库分表,主要是五张表

2.数据表拆分原则

经过对五张表的调用梳理发现,这五张表使用的字段为会员号、手机号、卡号和虚拟卡号这几个表字段,对此我们每张表确定一个主要拆分字段,需要关联查询的情况新建一张中间映射表,所以最后将五张表变成了八张表(含三张关联表)。主要拆分原则是:

  1. 分库分表需要考虑未来多租户等扩展场景,能支持按业务维度来进行切分;
  2. 会员分库分表主要考虑在线业务,离线业务不在考虑范围内
  3. 分库分表优先考虑优先级高的接口

 

3. 拆分策略

基于业务对拆分策略进行分析

根据2018年相关表的数据增长量统计为

序号

表名

2018年4月数据量

2019年3月数据量

增长量

1

A

15063400

23351297

8287897

2

B

14793400

23087874

8294474

3

C

21412500

33707846

12295346

4

D

83906300

99358704

15452404

5

E

21669200

32926241

11257041

五张表的增长量在800万-1500万之间,在未来5年预计表的总数据为

序号

表名

2019年3月数据量

未来5年总量

备注

1

A

23351297

63351297

按年800万增长量预估

2

B

23087874

63087874

按年800万增长量预估

3

C

33707846

93707846

按年1200万增长量预估

4

D

99358704

174358704

按年1500万增长量预估

5

E

32926241

87926241

按年1100万增长量预估

最后确定拆分策略为:

将表拆分的数据库数量为4个库,单个数据库分为10张表。

落库取模基数为4,落表取模基数为10

Hash(key)%4=m

Hash(key)%10=n

数据库

n

库1

0

1

2

3

以此内推

表1

表2

表3

表4

 

库2

同上

 

库3

同上

 

库4

同上

 

按此方案折分后五年各表数据量为

序号

表名

未来5年总量

未来5年各表管理数据量

备注

1

A

63351297

142万-174万

按各表10%分布误差进行计算

2

B

63087874

142万-174万

3

C

93707846

210万-256万

4

D

174358704

390万-480万

5

E

87926241

198万-242万

 

未来5年最大单表管理数据约为480万,在mysql数据管理范围内,所以按以上方案拆分能满足未来5年业务预估增长量。

 

4. 改造方案

根据改造范围我们对五张表使用场景进行了梳理,梳理出所个场景使用的sql情况(dao层使用mybatis),特别是复杂sql的梳理,从以上梳理结果看可以分为几类:

  1. 涉及子查询以及left join等复杂查询的sql;
  2. 涉及非分库分表字段情况;
  3. 模糊查询

通过对梳理结果的分类整理,我们确定本次以下处理策略:

  1. 能取消的left join就取消,找业务确认
  2. 不能取消的接口改造,新增加dao层支持新的改造,(按四个步骤),聚合在atom层做
  3. 涉及跨表查询分页的放es去做
  4. 涉及非分库分表主键的去掉或在es处理,
  5. 模糊查询由es处理
  6. 前端配合调整

为了最小化改造,我们增加了Es和聚合层(主要是对复杂sql的聚合功能),并对原有dao层进行改造

 

5. 实施阶段

  1. 梳理现在DAO,对应表,清理代码,确定需要增加的DAO(拉分支)
  2. 折分jar包(dao重构
  3. 新加DAO
  4. 开发逻辑
  5. 测试
  6. 验收
  7. 演练
  8. 上线

 

 

 

三、生产切换方案及数据迁移

生产我们切换采用四个阶段,通过设置枚举类指定开关状态

0 初始状态,单表及相关操作

1 双写,查询按单表(旧)的方式实现

2 双写,查询按分表(新)的方式实现

3 单写(新),查询按分表(新)的方式实现

 

上线的数据迁移开发了一个的数据迁移程序,采用java多线程调用存储过程的方式。本次上线为了保证业务一直在线,我们在上线方案中使用了Canal+proxy的方案

 

主要分为三部分,

  1. 分库数据迁移。分库是新增加的库,可以提前进行数据迁移,使用Canal作为从库的一个从库来监听从库数据变化
    1. 停主从同步;
    2. 运行数据迁移程序
    3. 将从库binlog重置
    4. 搭建Canal+proxy同步
    5. 重新开始主从同步
  2. 初始状态为0的版本发布。
  3. 状态切换为1。
  4. 最新数据状态同步,断开Canal+proxy

 

数据切换中遇到shardingsphere的坑:

 

  1. 4.0.0以下版本的sharding-proxy不支持基于字符的分表策略
  2. 4.0.0-rc1的版本在分表时出现部分字段解析为null,使用的解析类为org.apache.shardingsphere.core.parse.old.parser.expression.SQLTextExpression,在shardingshpere中有提issue,在rc2的版本中解决了,参考:https://github.com/apache/incubator-shardingsphere/issues/2696

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL分库分表是一种数据库分布式架构的实践方案,旨在解决大数据量、高并发访问等问题。在实践中,可以采取以下步骤: 1. 数据库的垂直拆分:将一个大型数据库拆分成多个功能相关的小型数据库。例如,可以将用户信息存储、商品信息存储等拆分成独立的数据库,便于管理和维护。 2. 数据库的水平拆分:将某个数据库中的表按照某种规则拆分成多个分表,例如按照用户ID哈希值进行拆分。这样每个分表只负责一部分数据的存储和查询,提高查询性能。 3. 集群和分布式处理:通过数据分片策略,将数据分布在不同的数据库实例上,形成一个数据库集群。每个数据库实例可以部署在不同的服务器上,提供更高的容错性和可用性。 4. 数据同步和一致性:在分库分表架构中,需要保持数据的一致性。可以通过主从复制、双写一致性、分布式事务等机制来实现数据的同步和一致性。 5. 路由和负载均衡:在分库分表的架构中,需要通过路由器来确定每个查询应该路由到哪个数据库实例和表中。同时,为了提高性能和可扩展性,可以通过负载均衡技术将查询请求均匀地分发到各个数据库节点。 总的来说,MySQL分库分表实践是一种将大型数据库拆分成小型数据库和分表,通过集群和分布式处理来提高性能和可扩展性的架构方案。在实施过程中需要注意数据的一致性和同步,以及合理的路由和负载均衡策略。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值