分库分表设计方案

6 篇文章 0 订阅

一、为什么要分库分表?
随着业务的不断发展,数据量不断增加,因此数据操作,如增删改查的开销也会越来越大,原来基于单库单表的设计已经不能满足存储需求,数据库随时面临爆库风险;

再加上物理服务器的资源有限(CPU、磁盘、内存、IO 等)。最终数据库所能承载的数据量、数据处理能力都将遭遇瓶颈。

二、如何解决?
1、增加存储这只能暂时缓解,但也可能是一种性价比比较高的方案

2、数据实现动静分离,定时备份到达终态数据,缓解存储压力

例:

热数据:3个月内的订单数据,查询实时性较高;(mysql中分库分表)

冷数据A:3个月 ~ 12个月前的订单数据,查询频率不高;(es中)

冷数据B:1年前的订单数据,几乎不会查询,只有偶尔的查询需求;(hive)

3、数据库分表可以解决单表海量数据的查询性能问题,分库可以解决单台数据库的并发访问压力问题。有时候,我们需要同时考虑这两个问题,因此,我们既需要对单表进行分表操作,还需要进行分库操作,以便同时扩展系统的并发处理能力和提升单表的查询性能,就是我们使用到的分库分表。

三、分库分表的实现方案
拆分的方式有两种,一种是水平拆分,一种是垂直拆分,分库分表是对数据库拆分的解决方案;根据分库分表方案中实施切片逻辑不同,我们将分库分表的实现方案分成三大类:客户端,代理分片,分布式数据库

1、客户端
客户端分片就是使用分库分表数据库的应用层直接操作分片逻辑,分片规则需要在同一应用的多个模块进行同步,每个应用嵌入一个操作分片的逻辑实现,一般都通过依赖jar实现,具体的实现方式分为三种:一种在应用层直接实现,第二通过ORM框架实现;第三通过定制JDBC协议实现;

应用层实现:
       这是一种通用的简单的实现方案,直接在应用层读取分片规则实现路由逻辑,然后应用层自己决定访问那个实例,那个库,那个表,那个字段等等。

 架构如下:

在这里插入图片描述

这种方案虽然侵入了业务,但是实现比较简单,适合快速上手,出问题也比较好查,目前有一些开源实现dbsplit方案

ORM框架实现:
通过定制ORM框架中或者通过框架的扩展机制来实现分库分表的逻辑,现在很多公司通过mybatis配置文件的SQL中的表索引的参数来实现分片;

在这里插入图片描述

mybatis实现分库分表方式:

在这里插入图片描述

在这里插入图片描述

此方案也是推荐方案

JDBC协议实现:
我们通过定制JDBC协议来实现,针对业务提供JDBC一致的接口,让业务方无需关系分库分表的实现,让分库分表规则在JDBC内部实现,对业务方透明;

架构如下:
在这里插入图片描述
在这里插入图片描述

ShardingSphere-JDBC体系结构

这种解决方案对业务透明,不侵入业务,让开发人员更大限度聚焦在逻辑实现上,但开发人员需要理解并使用JDBC协议;现在流行的框架:shardingsphere,前身是sharding-jdbc由当当开发,现目前已经交给apahce了

https://github.com/apache/incubator-shardingsphere

使用限制:

对于部分SQL语法不支持,比如:having,union,or,批量插入insert into values(v1,v2),(v3,v4),distinct,不支持子查询

2、代理分片
代理层是在应用层和数据库层增加一个代理层,把分片规则配置在代理层,代理层对外提供与JDBC兼容的接口给应用层,业务也不用关系分片规则

在这里插入图片描述

这种方案的优点是对业务透明,缺点是增加一层网络代理,对性能有损失;

在这里插入图片描述

3、分布式数据库
通过将分片功能在DB内部实现来实现分布式存储,对业务透明;

架构如下:
在这里插入图片描述

业界的开源实现,阿里的OceanBase,开源的tidb和度小满nesiodb

四、案例分析
1、billing模块t_bill_record数据超两千万条

在这里插入图片描述

水平拆分,以周为单位,提前建好两年的表t_bill_record_yyyymmdd
新增数据根据当前时间进入对应的表中
查询数据根据时间跨度,联合查询的表数据
数据迁移(尽量不要影响正在使用中的表,如果有影响,对于insert/update/delete,每次处理1000行数据,执行commit,之后sleep 1秒。对于select,每次查询2000行数据,之后sleep1秒)

2、亿级订单系统设计
订单表为例,在订单表中,订单id肯定是不可重复的,因此将该字段当做shard key 是非常适合的,其他表类似。
例:单张order表分为10个库,每个库100个表
中间变量 = shard_key / (库数量*单个库的表数量)
库序号 = 取整(中间变量/单个库的表数量)
表序号 = 中间变量 % 单个库的表数量,

如果shard_key 不是整数类型,可以先hash 在进行取模,

例如: hash(shard_key) % 库容量

数据迁移(双写迁移方案)
就是在线上系统,之前所有写库的地方,增删改操作,除了对旧库增删改,都加上对新库的增删改,这就是所谓双写 — 同时写俩库(旧库和新库)
同时起一个job,同步旧库数据到新库,接着当数据完全一致了,上线所有操作到新库服务

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值