什么是分库分表?
为了算数据库的压力,采用分库分表的方案,将一个表结构分为多个表,或者将一个表的数据分后
放入多个表,这些表可以放在同一库里,也可以放到不同的库里,甚至可以放在不同的数据库实例上。
垂直拆分与水平拆分
垂直拆分: 根据业务的维度,将原本的一个库(表)拆分为多个库(表),每个库(表)与原有的结构不同。
**水平拆分: ** 根据分片算法,将一库(表)拆分为多个库(表),每个库(表)依旧保留原有的结构。
垂直拆分与水平拆分可能回同时存在,但在微服务中常采用水平拆分。
数据库的三个阶段
1.单库单表
单库单表是最常见的数据库设计,例如,有一张用户表(以下简称User表)都放在数据库中,所有的用户信息都存在这张User表中。
**2.单库多表 **
随着用户量的猛增,User表中的数据量越来越大,当数据量达到一定的程度时,对User表的查询会逐渐变慢,会影响整个数据库的性能,可能会出现Mysql锁表的现象,所有的写操作只能等待了。
3.多库多表
数据量的猛增,单台数据库的存储空间就会不够用,并随着查询量的猛增,单台数据库的服务器也无法支撑,单表的数据量太大,即使增加或减少索引,也会耗时过长。对数据库的水平切分,将切分的数据库和表水平低分散到不同的数据库实例上。
什么情况下需要分库分表?##
如果数据库中数据量达到了一定的量级,则需要进行分表,分表单表的大数据量对索引查询带来的压力,并方便对索引和表结构变更
如果数据量的吞吐量到达瓶颈,就需要增加数据库的实例,利用多个数据库实例来分解大量的数据库请求带来的系统压力
如果希望在扩容时对应用层的配置改变最少,就需要在每个数据库实例中预留足够的数据库数量
##三种分而治之的解决方案##
拆分的方式有2种:垂直拆分和水平拆分,分库分表是对数据库拆分的一种解决方案。根据分库分表方案中的实施切片的逻辑的层次不同,分库分表的实现方案分为大类:客户端分片,代理分片,支持事务的分布式的数据库。
** 1.客户端分片**
客户端分片就是使用分库分表的数据库的应用层直接操作分片逻辑,分片规则需要在同一个应用的多个节点间进行同步,每个应用层都嵌入一个操作切片的逻辑实现(分片规则),这一般通过依赖Jar包来实现。如上图,具体的实现方式分为三种:在应用层直接实现,通过定制JDBC协议实现,通过定制ORM框架实现。
在应用层直接实现
在应用层直接读取分片规则,然后解析分片规则,根据分片规则实现切分的路由逻辑,从引用层直接决定每次操作应该使用哪个数据库实例,数据库与对应的表等。随倾入业务,但实现简单,而且切分逻辑是自己开发,即使出现问题,也容易定位,方便解决。通过定制JDBC协议实现
定制的JDBC协议,是为了让开发更好关注业务逻辑实现,不用更多关注分库分表的实现,让分库分表在JDBC内部实现,对业务层保持透明。但开发需要理解JDBC协议才能实现分库分表的逻辑。Sharding JDBC 就是采用这种方案。通过定制ORM框架实现
ORM的广泛应用与扩展,就有了定制的ORM框架实现的分库分表方案,也就是把分片规则实现到ORM框架中或通过ORM框架支持的扩展机制来完成分库分表的逻辑
** 2.代理分片**
代理分片就是在应用层与数据库层增加一个代理层,把分片的路由规则配置在代理层,代理层对外提供与JDBC兼容的接口给应用层,不用过多关心分片规则,只需关心业务逻辑的开发。如下图
- 优点:让应用层的开发专注业务逻辑的实现,把分库分表的配置留给代理层(代理分片的实现框架有,Mycat,Cobar等)
- 缺点:增加了代理层,尽管代理层是轻量级的转发协议,但要实现JDBC协议的解析,并通过路由的规则来路由请求,对每个数据库操作都增加了一层网络传输,对性能是由有影响,需要维护增加的代理层,也是有硬件成本。
** 3.支持事务的分布式数据**
OceanBase,TiDB 等都对外提供可伸缩的体系架构,并提供一定的分布式事务支持,将可伸缩的特点和分布式事务的实现包装到分布式数据库内部实现。