1. 数据库架构演变与分库分表介绍

1.1 海量数据存储问题及解决方案

如今随着互联网的发展,数据的量级也是成指数的增长,从GB到TB到PB。对数

据的各种操作也是愈加的困难,传统单体的关系性数据库已经无法满足快速查

询与插入数据的需求。

阿里数据中心内景( 阿里、百度、腾讯这样的互联网巨头,数据量据说已经接近

EB级)

遇到的问题

java 复制代码
1.用户请求量大
2.单库的数据量过大
3.单表的数据量过大

解决方案

java 复制代码
单机数据库 --> 主从架构 ---> 分库分表

1.2 项目架构的演进

1.2.1 理财平台 - V1.0

此时项目是一个单体应用架构 (一个归档包(可以是JAR、WAR、EAR或其它归

档格式)包含所有功能的应用程序,通常称为单体应用)

这个阶段是公司发展的早期阶段,系统架构如上图所示。我们经常会在单台服

务器上运行我们所有的程序和软件。

在项目运行初期,User表、Order表、等等各种表都在同一个数据库中,每个

表都包含了大量的字段。在用户量比较少,访问量也比较少的时候,单库单表

不存在问题。

这个阶段一般是属于业务规模不是很大的公司使用,因为机器都是单台的话,

随着我们业务规模的增长,慢慢的我们的网站就会出现一些瓶颈和隐患问题

1.2.2 理财平台 - V1.x

随着访问量的继续不断增加,单台应用服务器已经无法满足我们的需求。所以

我们通过增 加应用服务器的方式来将服务器集群化。


存在的问题

采用了应用服务器高可用集群的架构之后,应用层的性能被我们拉上来了,但是数

据库的负载也在增加,随着访问量的提高,所有的压力都将集中在数据库这一层.

1.2.3 理财平台-V2.0 版本
复制代码
如何去提高数据库层面的性能呢?

数据库主从复制、读写分离

写10000 -> 3分钟, 读10000->5秒, 读操作占整体操作8成,写操作2成。

读写分离的数据节点中的数据内容是一致。

使用主从复制+读写分离一定程度上可以解决问题,但是随着用户量的增加、访

问量的增加、数据量的增加依然会带来大量的问题.

1.2.4 理财平台-V2.x 版本

随着访问量的持续不断增加,慢慢的我们的系统项目会出现许多用户访问同一

内容的情况,比如秒杀活动,抢购活动等。

那么对于这些热点数据的访问,没必要每次都从数据库重读取,这时我们可以

使用到缓存技术,比如 redis、memcache 来作为我们应用层的缓存。

数据库主从复制、读写分离 +缓存技术

存在的问题

java 复制代码
1.缓存只能缓解读取压力,数据库的写入压力还是很大
2.且随着数据量的继续增大,性能还是很缓慢

随着数据库的压力持续增加,数据库的瓶颈仍然是个最大的问题。因此我们可以考虑对数据的垂直拆分和水平拆分。

1.3 分库分表

1.3.1 什么是分库分表

简单来说,就是指通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机)上面,以达到分散单台设备负载的效果。

1.3.2 分库分表的方式
复制代码
分库分表包括: 垂直分库、垂直分表、水平分库、水平分表 四种方式。
1.3.2.1 垂直分库

数据库中不同的表对应着不同的业务,垂直切分是指按照业务的不同将表进行分类,分布到不同的数据库上面。

将数据库部署在不同服务器上,从而达到多个服务器共同分摊压力的效果。

1.3.2.2 垂直分表

表中字段太多且包含大字段的时候,在查询时对数据库的IO、内存会受到影响,同时更新数据时,产生的binlog文件会很大,MySQL在主从同步时也会有延迟的风险。

java 复制代码
1.将一个表按照字段分成多表,每个表存储其中一部分字段。

垂直拆分带来的一些提升

java 复制代码
1.解决业务层面的耦合,业务清晰
2.能对不同业务的数据进行分级管理、维护、监控、扩展等
3.高并发场景下,垂直分库一定程度的提高访问性能
1.3.2.3 水平分库

将单张表的数据切分到多个服务器上去,每个服务器具有相应的库与表,只是表中数据集合不同。 水平分库分表能够有效的缓解单机和单库的性能瓶颈和压力,突破IO、连接数、硬件资源等的瓶颈.

简单讲就是根据表中的数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上面, 例如将订单表 按照id是奇数还是偶数, 分别存储在不同的库中。

1.3.2.4 水平分表

针对数据量巨大的单张表(比如订单表),按照规则把一张表的数据切分到多张表里面去。 但是这些表还是在同一个库中,所以库级别的数据库操作还是有IO瓶颈。


总结

垂直分表 : 将一个表按照字段分成多表,每个表存储其中一部分字段。
垂直分库 : 根据表的业务不同,分别存放在不同的库中,这些库分别部署在不同的服务器.
水平分库 : 把一张表的数据按照一定规则,分配到不同的数据库,每一个库只有这张表的部分数据.
水平分表: 把一张表的数据按照一定规则,分配到同一个数据库的多张表中,每个表只有这个表的部分数据.

1.4 分库分表的规则

水平分库规则

java 复制代码
1.不跨库、不跨表,保证同一类的数据都在同一个服务器上面。
2.数据在切分之前,需要考虑如何高效的进行数据获取,如果每次查询都要跨越多个节点,就需要谨慎使用。

水平分表规则

1. RANGE划分

java 复制代码
时间:按照年、月、日去切分。
地域:按照省或市去切分。
大小:从0到1000000一个表。

2. HASH

java 复制代码
用户ID取模

1.5 分库分表带来的问题及解决方案

1.5.1 事务一致性问题

当我们需要更新的内容同时分布在不同的库时, 不可避免的会产生跨库的事务问题. 原来在一个数据库操作, 本地事务就可以进行控制, 分库之后 一个请求可能要访问多个数据库,如何保证事务的一致性,目前还没有简单的解决方案.

1.5.2 跨节点关联的问题

在分库之后, 原来在一个库中的一些表,被分散到多个库,并且这些数据库可能还不在一台服务器,无法关联查询.解决这种关联查询,需要我们在代码层面进行控制,将关联查询拆开执行,然后再将获取到的结果进行拼装.

1.5.3 分页排序查询的问题

分库并行查询时,如果用到了分页 每个库返回的结果集本身是无序的, 只有将多个库中的数据先查出来,然后再根据排序字段在内存中进行排序,如果查询结果过大也是十分消耗资源的.

1.5.4 主键避重问题

在分库分表的环境中,表中的数据存储在不同的数据库, 主键自增无法保证ID不重复, 需要单独设计全局主键.

1.5.5 公共表的问题

不同的数据库,都需要从公共表中获取数据. 某一个数据库更新看公共表其他数据库的公共表数据需要进行同步.

相关推荐
小虾米vivian2 小时前
达梦:将sql通过shell脚本的方式放在后台执行
服务器·数据库·sql
专注代码七年3 小时前
查询 mysql中 所有的 非空记录字段
数据库·mysql
a.3023 小时前
OpenCV(cv2)学习笔记:从模板匹配入门到常用函数
数据库·ubuntu·ssh
大视码垛机3 小时前
速度与安全双突破:大视码垛机重构工业自动化新范式
大数据·数据库·人工智能·机器人·自动化·制造
向上的车轮4 小时前
如何用 Rust 重写 SQLite 数据库(二):是否有市场空间?
数据库·rust·sqlite
jc06204 小时前
4.2-中间件之MySQL
数据库·mysql
熊文豪4 小时前
KingbaseES读写分离集群架构解析
数据库·架构·kingbasees·金仓数据库·电科金仓
伤心男孩拯救世界(Code King)4 小时前
【MySQL】--- 表的约束
数据库·mysql