MySQL运维 - 分库分表
概述
随着互联网及移动互联网的发展,应用系统的数据量也是成指数式增长,若采用单数据库进行数据存储,存在以下性能瓶颈:
IO瓶颈:热点数据太多,数据库缓存不足,产生大量磁盘IO,效率较低。请求数据太多,带宽不够,网络IO瓶颈。
CPU瓶颈:排序、分组、连接查询、聚合统计等SQL会耗费大量的CPU资源,请求数太多,CPU出现瓶颈。
为了解决上述问题,需要对数据库进行分库分表处理。
中心思想:将数据分散存储,使得单一数据库/表的数据量变小来缓解单一数据库的性能问题,从而达到提升数据库性能的目的。
拆分策略
分库分表的形式,主要是两种**:垂直拆分和水平拆分**。而拆分的粒度,一般又分为分库和分表,所以组成的拆分策略最终如下:
垂直拆分
垂直拆分又称为纵向拆分,垂直拆分是将表按库进行分离,或者修改表结构按照访问的差异将某些列拆分出去。应用时有垂直分库和垂直分表两种方式,一般谈到的垂直拆分主要指的是垂直分库。
垂直分库**:按数据库中表的密集程度部署到不同的库中**,例如将原来的电商数据库垂直切分成商品数据库、用户数据库等。
垂直分表**:将一张表中不常用的字段拆分到另一张表中**,从而保证第一张表中的字段较少,避免出现数据库跨页存储的问题,从而提升查询效率。
垂直分库
垂直分库:以表为依据,根据业务将不同表拆分到不同库中。
特点:
- 每个库的表结构都不一样。
- 每个库的数据也不一样。
- 所有库的并集是全量数据。
垂直分表
垂直分表:以字段为依据,根据字段属性将不同字段拆分到不同表中。
特点:
- 每个表的结构都不一样。
- 每个表的数据也不一样,一般通过一列(主键/外键)关联。
- 所有表的并集是全量数据。
优缺点
优点:
- 拆分后业务清晰,拆分规则明确;
- 易于数据的维护和扩展;
- 可以使得行数据变小,一个数据块 (Block) 就能存放更多的数据,在查询时就会减少 I/O 次 数;
- 可以达到最大化利用 Cache 的目的,具体在垂直拆分的时候可以将不常变的字段放一起,将经常改变的放一起;
- 便于实现冷热分离的数据表设计模式。
缺点:
- 主键出现冗余,需要管理冗余列;
- 会引起表连接 JOIN 操作,可以通过在业务服务器上进行 join 来减少数据库压力,提高了系统的复杂度;
- 依然存在单表数据量过大的问题;
- 事务处理复杂。
水平拆分
水平拆分又称为横向拆分,它不再将数据根据业务逻辑分类,而是通过某个字段(或某几个字段),根据某种规则将数据分散至多个库或表中,每个表仅包含数据的一部分,通常使用Hash算法去拆分,使得具有相同属性的内容落到同一个数据库中。(hash(key) % NUM_DB)
水平分表是将一张含有很多记录数的表水平切分,不同的记录可以分开保存,拆分成几张结构相同 的表。如果一张表中的记录数过多,那么会对数据库的读写性能产生较大的影响,虽然此时仍然能 够正确地读写,但读写的速度已经到了业务无法忍受的地步,此时就需要使用水平分表来解决单个单个数据库的读写压力问题。
水平分库
水平分库:以字段为依据,按照一定策略,将一个库的数据拆分到多个库中。
特点:
- 每个库的表结构都一样。
- 每个库的数据都不一样。
- 所有库的并集是全量数据。
水平分表
水平分表:以字段为依据,按照一定策略,将一个表的数据拆分到多个表中。
特点:
- 每个表的表结构都一样。
- 每个表的数据都不一样。
- 所有表的并集是全量数据。
优缺点
优点:
- 拆分规则设计好,join 操作基本可以数据库做;
- 不存在单库大数据,高并发的性能瓶颈;
- 切分的表的结构相同,应用层改造较少,只需要增加路由规则即可;
- 提高了系统的稳定性和负载能力。
缺点:
- 拆分规则难以抽象;
- 跨库Join性能较差;
- 分片事务的一致性难以解决;
- 数据扩容的难度和维护量极大。
在业务系统中,为了缓解磁盘IO及CPU的性能瓶颈,到底是垂直拆分,还是水平拆分;具体是分库,还是分表,都需要根据具体的业务需求具体分析。
实现技术
shardingJDBC:基于AOP原理,在应用程序中对本地执行的SQL进行拦截,解析、改写、路由处理。需要自行编码配置实现,只支持java语言,性能较高。
MyCat:数据库分库分表中间件,不用调整代码即可实现分库分表,支持多种语言,性能不及前者。
总结
水平拆分:解决表中记录过多问题。
垂直拆分:解决表过多或者是表字段过多问题