一、前言:为什么还需要继续学习分库分表和微服务?
在前面的学习中,我们已经接触了单体架构、应用服务器与数据库分离、负载均衡、数据库读写分离以及 Redis 缓存
通过这些知识,我们已经知道:当系统访问量不断增加时,可以通过增加应用服务器、分担数据库读请求,以及使用 Redis 缓存热点数据等方式改善系统的性能
但是,这些方案是否能够解决所有问题呢?
答案是否定的
假设现在我们正在开发一个大型电商网站,网站中包含用户、商品、订单、支付等业务
随着用户数量不断增加,可能会出现以下问题:
-
数据库中的订单数据越来越多,单张订单表变得非常庞大
-
大量用户同时创建订单,数据库的写入压力越来越大
-
即使使用 Redis 缓存,仍然有许多请求需要访问数据库
-
用户、商品、订单等业务不断增加,整个应用程序的代码也越来越复杂
-
不同业务的访问量不同,有些业务需要扩容,而另一些业务可能并不需要
这些问题说明,我们需要从两个不同的角度继续优化系统:
-
数据库层面: 通过分库分表等方式,调整数据的存储与访问方式
-
应用架构层面: 通过微服务等架构设计方式,调整业务模块的组织、部署与扩展方式
二、数据库分库分表
为什么需要
前面讲到的数据库读写分离,是将写任务交给一个主库,读操作交给多个从库,但是当我们数据库的数据量持续激增,或者写请求成为了主要瓶颈的时候,我们为了应对更多的请求以及更好的分配数据,我们自然而然就会想到将请求都按一定的要求分出来,其中就包含了垂直拆分以及水平拆分,简单来说垂直拆分就是按照具体的业务来,水平拆分就是单纯按照数据行来分;而分库以及分表就是说一个是将数据分到多个数据库中,一个是在数据库中建立多个表,不过要注意一点的是分库分表不代表说一定是引入多台设备,这样来增加数据库以及更多的表,而是有多种部署方式的,第一种就是一台服务器,然后多个表,例如一台服务器运行MySQL,将订单数据拆分为orders0和orders1两张表中,这个是分表;第二种是一台服务器,多个数据库实例或者逻辑数据库(这里我们理解一下实例以及逻辑,实例:可以理解为是你电脑上实际启动的MySQL程序,它启动之后形成的一个独立的运行环境,那这么说我一台电脑是不是只能启动一个MySQL实例了,并不是的,如果要创建多个MySQL实例的话需要启动多个独立的MySQL进程,并且分配不同的端口号,然后分配各自独立的数据目录,这样就是多个实例了,不够他们依旧是同时共享这台电脑的 CPU、内存和磁盘硬件资源,那逻辑数据库是什么:就是你在一个实例中create database,这样就是一个逻辑数据库了,你就可以在一个实力当中创建多个,那多表就是create多个table),第三种就是我们很多人会想到的多台服务器来分别存储设备了,这样可以更有利于计算存储等
分库分表会带来哪些问题?
问题一:查询变复杂
假设用户需要查询自己的全部订单,但订单被拆分到了多个数据库中。
系统可能需要根据用户 ID 或订单 ID 确定数据所在的位置。
如果查询条件无法直接定位目标数据库,可能需要查询多个分片,再合并结果
问题二:全局 ID 生成
假设不同数据库中的订单表都使用从 1 开始自增的 ID,就可能出现重复。
例如:
订单库1:订单 ID = 1
订单库2:订单 ID = 1
这会让订单标识产生冲突
问题三:跨库事务更加复杂
假设创建订单需要同时修改订单数据和其他业务数据,而这些数据已经分布在不同数据库中,那么原本在单个数据库中可以完成的事务,可能变成跨数据库操作
问题四:扩容和数据迁移
如果最初将订单数据分到两个数据库中,后来数据量进一步增加,可能需要增加更多数据库。
此时需要考虑如何重新分配已有数据、如何保证数据迁移期间的读写正确性,以及如何避免影响业务运行。
因此,分库分表能够解决一部分规模问题,但也会增加开发、运维和排查问题的难度。
引入微服务

微服务简单来说就是解决人的问题,就是一个项目中要分成多个模块,每个模块细分,分成一个一个小任务来分配让一部分人负责一部分地方,这样就可以很好的修改以及问题检查
就比如一个电商系统就可以分为四个部分,用户服务,商品服务,订单服务以及支付服务,每个服务负责一块地方,并且每个服务通常可以独立运行部署以及扩容等
三、把分布式系统的知识串起来
现在,我们已经学过了应用服务器扩展、负载均衡、数据库读写分离、Redis 缓存、分库分表和微服务。
它们看起来都是为了解决系统性能或规模问题,但各自的作用并不相同
整体对比
| 技术 | 主要解决的问题 |
|---|---|
| 增加应用服务器 | 单个应用实例处理能力不足 |
| 负载均衡 | 如何将请求分配给多个实例 |
| 数据库读写分离 | 如何分担数据库读写负载 |
| Redis 缓存 | 如何减少重复访问数据库 |
| 数据库分库分表 | 如何管理和分散大规模数据 |
| 微服务 | 如何让复杂业务能够相对独立地开发、部署和扩展 |
