数据库分库分表

209 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。


分库:原本存储于一个库的数据分块存储到多个库上

应用场景:1)库中表过多,2)单台机器容量不够,3)访问量太大。

分库分表解决的最大痛点是数据库单点瓶颈,这个瓶颈的产生是由现代二进制数据存储体系决定的(即 I/O 速度)。  

三种方式

①不分表分库:将数据量比较大的几张表分散到不同的库,分散单库的压力

②垂直分表分库:将大表按照列拆分成多个表,然后再将这些表部署到不同的库上(关系密切的列组合划分)

②水平分表分库:将大表按照行拆分成多个表,然后再将这些表部署到不同的库上(可以看成是相同字段的分组,比如相同用户的数据)

 

(1) 分库分表存在的问题****

事务管理:在执行分库分表之后,由于数据存储到了不同的库上,数据库事务管理会出现困难。

关联查询:分库分表之后,难以避免会将原本逻辑关联性很强的数据划分到不同的表、不同的库上,这时,表的关联操作将受到限制

数据管理:额外的数据管理负担和数据运算压力,最显而易见的就是数据的定位问题和数据的增删改查的重复执行问题

 

(2) 分布式数据库中间件****

分库分表的技术方案总体上来讲分为两大类:应用层依赖类中间件、中间层代理类中间件

 

(3) 应用层依赖类中间件****

这类分库分表中间件的特点就是和应用强耦合,需要应用显示依赖相应的jar包,比如知名的TDDL、当当开源的sharding-jdbc、蘑菇街的TSharding、携程开源的Ctrip-DAL等。我们以sharding-jdbc为例,其架构图如下所示:

image.png

此类中间件的基本思路,就是重新实现JDBC的API,通过重新实现DataSource、PrepareStatement等操作数据库的接口,让应用层在基本不改变业务代码(需业务自行定义路由规则)的情况下透明地实现分库分表的能力。

中间件给上层应用提供熟悉的JDBC API,内部通过一系列的准备工作获取真正可执行的sql,然后底层再按照传统的方法(比如数据库连接池)获取物理连接来执行sql,最后把数据结果合并处理成ResultSet返回给应用层。

优点:无需额外部署,性能损耗低,无中心化

缺点:不支持异构语言,与应用强耦合,SQL支持能力较弱(受应用影响),连接消耗数高,需要改代码

(4) 中间层代理类中间件****

这类分库分表中间件的核心原理是在应用和数据库的连接之间搭起一个代理层,上层应用以标准的MySQL协议来连接代理层,然后代理层负责转发请求到底层的MySQL物理实例,这种方式对应用只有一个要求,就是只要用MySQL协议来通信即可

比较有代表性的产品有开创性质的Amoeba、阿里开源的Cobar、Mycat 、当当开源的sharding-proxy,奇虎360开源的Atlas等。我们以sharding-proxy为例,其架构图如下所示:

image.png

优点:支持异构语言,与应用完全解耦,SQL支持能力较强,连接消耗数低,不需要改代码

缺点:需连接消耗数,性能损耗略高,存在中心化

 

(5) 小结****

应用层依赖类中间件采用无中心化架构,适用于Java开发的高性能的轻量级OLTP应用(联机事务处理);

中间层代理类中间件提供静态入口以及异构语言的支持,适用于OLAP应用(联机分析处理)以及对分片数据库进行管理和运维的场景。

相对于分布式数据库,单机数据库的速度有明显的优势

采用什么样的数据库,取决于业务本身,如果单机数据库已经能满足你当前的业务需求并且也能满足可预期的未来一段时间的业务需求,那就没必要用分布式数据库。所以分布式数据库只是额外提供了一种选择,而不是对原有数据体系的完全颠覆。

zhuanlan.zhihu.com/p/134047902