MySQL

MySQL 分片

·11 分钟阅读·4205 字

整理 MySQL 分片 的核心概念、关键流程与实践要点

📋 目录

MySQL 分片

MySQL 分片(Sharding)的本质是:将一个逻辑上的大数据库拆分成多个物理数据库实例,让数据分散存储和访问,从而突破单机 MySQL 在容量、并发和性能上的瓶颈。

对于运维和云平台方向来说,理解分片不能只停留在“数据拆开了”,还需要理解为什么拆、怎么定位数据、查询怎么执行、带来的问题是什么。


1. 为什么需要 MySQL 分片

单机 MySQL 的能力存在上限。

假设有一个订单表:

CREATE TABLE orders(
    id BIGINT PRIMARY KEY,
    user_id BIGINT,
    amount DECIMAL(10,2),
    create_time DATETIME
);

随着业务增长:

订单量:
1000万
 ↓
1亿
 ↓
10亿
 ↓
100亿

单机可能出现:

1.1. 存储瓶颈

一台机器:

磁盘:
2TB

订单数据:
5TB

无法存储。


1.2. IO 瓶颈

大量查询:

select *
from orders
where user_id=10001;

大量写入:

insert into orders...

都会竞争:

磁盘IO
CPU
Buffer Pool
Redo Log
Binlog

1.3. 并发瓶颈

例如:

10万个请求/s

全部访问:

mysql-01
     |
 orders表

单点压力巨大。


所以需要:

           应用
             |
        分片中间件
             |
  ----------------------
  |          |          |
mysql-01  mysql-02  mysql-03

订单1      订单2      订单3

2. 分片的核心思想

假设原来:

orders表

id
1
2
3
4
5
6
7
8
9
10

全部在:

mysql-01

分片后:

mysql-01

1
2
3


mysql-02

4
5
6


mysql-03

7
8
9
10

应用访问时:

用户请求
   |
   |
判断数据在哪个库
   |
   |
访问对应MySQL

这个“判断规则”叫:

分片算法(Sharding Algorithm)


genui{“data_networks_databases_learning_block”:{“type_id”:“SQL_GROUP_BY”}}


3. 分片的三个关键概念

4. 分片键(Sharding Key)

决定数据放哪里的字段。

例如:

用户系统:

user
{
 id,
 name,
 phone
}

选择:

user_id

作为分片键。

原因:

用户相关数据天然绑定:

user_id=10001

订单
支付
购物车
地址

都可以放一起。


5. 分片规则

例如:

有4个数据库:

db0
db1
db2
db3

规则:

database = user_id % 4

例如:

用户:

10001

计算:

10001 % 4 = 1

所以:

db1

存储:

user_id=10001

整体:

user_id

10000
 |
10000%4=0

db0


10001
 |
10001%4=1

db1


10002
 |
10002%4=2

db2

6. 常见 MySQL 分片方式

主要有三种。


7. 水平分片(Horizontal Sharding)

最常见。

也叫:

分库分表

特点:

表结构一样,数据不同。

例如:

原来:

user_order

10亿行

拆:

order_db_0

2.5亿


order_db_1

2.5亿


order_db_2

2.5亿


order_db_3

2.5亿

每个库:

orders表

结构完全一样。


例如:

订单id

10001

计算:

10001 % 4 = 1


进入:

order_db_1.orders

优点:

  • 数据量下降

  • IO下降

  • 查询压力下降

缺点:

  • 跨库查询困难

例如:

以前:

select count(*)
from orders;

现在:

需要:

db0 count
+
db1 count
+
db2 count
+
db3 count

8. 垂直分片(Vertical Sharding)

按照业务拆。

例如:

原来:

用户库

user
order
payment
message

拆:

用户服务

user_db

user表


订单服务

order_db

order表


支付服务

payment_db

payment表

类似微服务数据库拆分。


优点:

业务隔离。

例如:

支付压力大:

只扩容:

payment_db

不用影响用户。


缺点:

业务关联查询复杂。

例如:

订单:

order

user_id

查询:

订单+用户信息

以前:

join

现在:

跨数据库:

order_db

      |
      |
      RPC

      |
user_db

9. 混合分片

大型互联网通常:

水平 + 垂直一起使用。

例如:

淘宝:

用户域

   |
 user_db

水平拆

user_db_0
user_db_1


订单域

order_db

水平拆

order_db_0
order_db_1

10. 分片以后 SQL 怎么执行?

这是最关键的问题。

以前:

select *
from orders
where user_id=10001;

MySQL:

直接执行。

分片以后:

应用首先计算:

user_id=10001

10001%4=1

知道:

order_db_1

然后:

发送:

select *
from order_db_1.orders
where user_id=10001;

这个过程叫:

路由(Routing)


11. 分片中间件

业务不可能每个人手写:

user_id % 4

所以出现中间件。

常见:

12. Apache ShardingSphere

架构:

应用

 |
 |
ShardingSphere

 |
 ----------------
 |       |       |
DB0    DB1     DB2

它负责:

  • SQL解析

  • 分片路由

  • SQL改写

  • 结果合并

例如:

用户:

select *
from orders
where user_id=10;

ShardingSphere:

分析:

user_id=10

10%4=2

改写:

select *
from db2.orders
where user_id=10;

13. Mycat

老牌分库分表中间件。


14. 分片最大的问题

很多人认为:

分片解决所有性能问题。

实际上:

分片引入大量复杂性。


15. 跨分片查询

例如:

查询:

select *
from orders
where create_time>'2026-01-01';

没有:

user_id

怎么办?

不知道在哪个库。

只能:

广播:

db0查询

db1查询

db2查询

db3查询

然后合并。

这叫:

Scatter-Gather

性能很差。


16. 分片扩容问题

假设:

原来:

4个库

规则:

user_id % 4

现在:

增加:

8个库

规则变:

user_id % 8

大量数据位置改变。

例如:

以前:

10001 %4=1

现在:

10001%8=1

有些幸运,但大量数据都会变化。

解决:

16.1. 一致性哈希

或者:

16.2. 预留分片

例如:

提前:

1024个逻辑分片

然后映射:

逻辑分片
    |
物理数据库

扩容只迁移部分。


17. 主键问题

以前:

AUTO_INCREMENT

每个库:

1
2
3

会冲突。

所以需要:

17.1. UUID

例如:

550e8400-e29...

缺点:

UUID随机:

索引性能差。


17.2. 雪花算法 Snowflake

现在比较常见:

时间戳
+
机器ID
+
序列号

生成:

180923847239847

特点:

  • 全局唯一

  • 趋势递增


18. MySQL 分片和主从复制有什么区别?

很多运维容易混淆。

19. 主从复制

解决:

读压力

结构:

      写

      |
    master

      |
--------------
|            |

slave1     slave2

数据:

完全一样。


20. 分片

解决:

数据量
+
写压力

结构:

db0

数据A


db1

数据B


db2

数据C

数据:

不同。


实际生产:

通常组合:

              应用

                |

          分片中间件

                |

 --------------------------------

 |              |               |

订单库0        订单库1          订单库2


master        master           master

 |
slave         slave            slave

21. 对云数据库运维来说,需要掌握哪些?

结合你的云运维和 AIOps 方向,我认为重点不是手写分片,而是理解:

22. (必须)

掌握:

  • 水平分片
  • 垂直分片
  • 分片键选择
  • 分片路由
  • 主从复制区别
  • 分片带来的运维问题

23. (生产运维)

需要理解:

  • ShardingSphere架构
  • MySQL Router
  • ProxySQL
  • 数据迁移
  • 分片扩容
  • 热点分片
  • 分片倾斜

例如:

某个用户:

user_id=888888

特别活跃:

订单100亿

导致:

db2 CPU 100%

其他库20%

这就是:

分片热点(Hot Sharding)

也是云数据库平台需要自动检测的问题。

24. (AIOps方向)

你以后做 AIOps,可以针对:

每个分片节点

CPU
IOPS
QPS
TPS
Buffer Pool
锁等待
复制延迟
慢SQL

建立:

异常检测

预测

自动迁移

自动扩容

关联文档

Yanche Blog

记录云原生、Linux、数据库等技术领域的学习心得,以及日常生活的思考与感悟。

© 2026 Yanche Blog. All rights reserved.

Powered by Astro