分布式数据库架构概述

懒驴 2023年01月10日 123次浏览

随着时间和业务的发展,分布式架构数据库中的数据量增长是不可控的,库和表中的数据会越来越多,随之带来的是更高的磁盘、IO、系统开销,甚至性能上的瓶颈。当数据库单表达到千万级别后SQL性能会开始下降。如果不对千万级数据表进行优化,SQL性能就会继续下降。

一台服务的资源终究会是有限的,因此需要对数据库和表进行拆分,从而更好的提供数据服务,提升SQL性能。

1.分库

分库的含义: 根据业务需要将原库拆分成多个库,提过降低单库的大小来提高单库的性能。常见的分库方式有两种--- 垂直分库水平分库
如下图所示:
分库示意图

(1)垂直分库

垂直分库是根据业务进行划分的,将同一类业务相关的数据库表划分在同一个库中。例如将原库中有关商品的数据表划分为一个数据库,将有关订单的数据表划分到另一个数据库。

(2)水平分库

水平分库是按照一定的规则对数据库进行划分。每个数据库中各个表的结构相同,数据存储在不同的数据库中。


2.分表

分表的含义: 根据业务需求将大表拆分成多个子表,通过降低单表的大小来提高单表的性能。常见的分表方式有两种:垂直分表水平分表 。如下图所示:
分表示意图

(1)垂直分表

垂直分表就是将一个大表根据业务功能拆分成多个分表。例如原表可根据业务分成基本信息表和详细信息表等。

(2)水平分表

水平分表是按照一定的规则对数据表进行划分。每个数据表的结果相同,数据存储在对各分表中。例如按照月份或者年份划分表。


3.水平切分的方式

水平分表或者水平分库都属于水平切分的方式。在真实业务场景中,强烈建议分库,而不是分表。因为分表依然共用一个数据库文件,仍然有磁盘IO的竞争,而分库能够很容易的将数据迁移到不同的数据库实例,甚至不同的数据库机器上,扩展性更好。
常见的水平切分方式有两种:范围法哈希法

(1)范围法

以范围法为例,如下图:
范围法示意图
如上图所示,以用户为中心的业务主键uid为划分依据,将数据水平切分到3个数据实例上去:
DB-1:存储0~10万的用户数据;
DB-2:存储10~20万的用户数据;
DB-3:存储20~30万的用户数据。

当然,我们也可以按照年份、月份进行水平划分:
DB1:存储2022年的用户数据;
DB2:存储2023年的用户数据;
DB3:存储2024年的用户数据。

(2)哈希法

哈希法简单示意图:
哈希法示意图
如上图所示,以用户主键uid为划分依据,将数据水平划分到3个数据库实例上:
DB-1:存储uid取模得0的uid数据;
DB-2:存储uid取模得1的uid数据;
DB-3:存储uid取模得2的uid数据。

小结:以上两种方法在互联网都有使用,其中哈希法使用得较为广泛。
在水平切片结构中,多个实例之间不直接产生联系,不像主从间Binlog同步。多个实例数据库的结果完全相同,多个实例存储的数据之间没有交集,所有实例间的数据并集构成全局数据。大部分互联网业务数据量很大,单库容量容易造成瓶颈,此时通过分片可以线性提升数据库的写性能,降低单库数据的容量。分片是解决数据库数据量大的问题而实施的架构设计。


4.垂直切分的方式

垂直分库或者垂直分表都属于垂直切分。在开发过程中,往往根据业务对数据进行垂直切分时,一般要考虑属性的长度访问频度 两个因素:

(1)长度较短、访问频率较高的放在一起;
(2)长度较长、访问频率较低的放在一起。

这是因为数据库会以行为单位将数据加载到内存里,在内存容量有限的情况下,长度短且访问频率高的属性,内存能够加载更多的数据,命中率会更高,磁盘IO会减少,数据库的性能会提升。
这里仍然可以以用户为例,可以这样进行垂直切分:
User 表(uid,uname,passwd,sex,age,...);
User_EX 表(uid,intro,sign,...)。

垂直切分开的表,主键都是uid,登录名、密码、性别、年龄等属性放在一个垂直表(库)中,自我介绍、个人签名等属性放在另外一个垂直表(库)中。垂直切分既可以降低单表(库)的数据量,又可以降低磁盘IO,从而提升吞吐量,但它与业务结合比较紧密,并不是所以业务都能够进行垂直切分的。


5.分组

分组的含义: 主和从构成的数据库集群称为“分组”。分组架构如下图所示:
分组示意图
在同一个组里的数据库集群,主从之间通过Binlog进行数据同步,多个实例数据库的结构完全相同,多个实例存储的数据也完全相同,本质上是将数据进行复制。
大部分互联网业务读多写少,数据库的读往往最先成为性能瓶颈。如果希望线性提升数据库的读性能,消除读写锁冲突,提升数据库的写性能,冗余从库实现数据的“读高可用”,那么可以使用分组架构。需要注意的是,在分组架构中,数据库的主库依然是写单点。