读写分离

场景

一年后,用户数突破百万。

我去看看系统监控,发现数据库的 CPU 和 I/O 使用率都很高:

数据库开始出现瓶颈。

问题分析

瓶颈分析:

  • 大部分请求是读操作
  • 写操作相对较少
  • 主库承担所有压力

读写分离

我决定采用数据库读写分离的方案:

API 服务 所有请求统一处理
MySQL 主库 读 + 写,CPU 85%
API 服务 读写路由分发
DB Router 读→从库,写→主库
MySQL 主库 仅处理写操作
MySQL 从库 仅处理读操作
API 服务集群 ×4 多实例部署
DB Router 轮询分配读请求
MySQL 主库 写操作
从库 1 读操作
从库 2 读操作
从库 3 读操作

从单节点数据库到读写分离的演进:

API 服务 所有请求统一处理
MySQL 主库 读 + 写,CPU 85%
API 服务 读写路由分发
DB Router 读→从库,写→主库
MySQL 主库 仅处理写操作
MySQL 从库 仅处理读操作
API 服务集群 ×4 多实例部署
DB Router 轮询分配读请求
MySQL 主库 写操作
从库 1 读操作
从库 2 读操作
从库 3 读操作

多从库架构

如果请求继续增长,我还可以增加更多的从库来分担读压力:

API 服务 所有请求统一处理
MySQL 主库 读 + 写,CPU 85%
API 服务 读写路由分发
DB Router 读→从库,写→主库
MySQL 主库 仅处理写操作
MySQL 从库 仅处理读操作
API 服务集群 ×4 多实例部署
DB Router 轮询分配读请求
MySQL 主库 写操作
从库 1 读操作
从库 2 读操作
从库 3 读操作

效果验证

效果验证

主库(Master) 仅写操作
QPS
2000 200
CPU
85% 25%
响应时间
200ms 50ms
从库(Slaves) 仅读操作
总 QPS
1800
读操作分散
平均 CPU
30%
平均响应时间
80ms

当前架构