读写分离中间件怎么选?ProxySQL 落地踩坑与选型对比

本文涉及的产品
RDS Agent(兼容OpenClaw),2核4GB
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
简介: ProxySQL是一款轻量高性能MySQL中间件,原生支持读写分离、自动故障切换与查询路由,相比MyCAT、ShardingSphere更专注、易用、低损耗,特别适合仅需主从读写分离的场景。

📌 关键词:ProxySQL、数据库中间件、读写分离、MyCAT、ShardingSphere、主从复制、查询路由、高可用


👋 大家好,我是数据库小学妹!

我们前面学完主从复制、读写分离,感觉动态数据源、AOP 注解、强制读主,这条路终于走通了。后面发现在Spring 配了两套数据源,事务里还要手动处理,加个从库就得改代码重新发版。连接池管理、故障切换这些更麻烦的事,我压根没考虑到。

最近我就把市面上主流的数据库中间件翻了个遍,最后选了 ProxySQL。今天把选型和踩坑的过程捋一遍,省得你再走我的弯路。


一、手写读写分离的痛点

初学读写分离时,手写代码确实轻量好用。但系统跑起来之后,问题一个个冒出来:

痛点 手写代码 中间件
新增从库 改代码、发版、重启 改配置,秒级生效
从库故障 代码判断连接失败再切主库 自动摘除故障节点
连接池 每个数据源单独配 统一管控
多语言 Java 写一套,Python 再写一套 任何语言连过来都行
负载均衡 自己实现轮询/权重 内置支持

说白了,中间件就是在应用和数据库之间加一层代理,脏活累活它全包了。


二、选型:为什么是 ProxySQL?

市面上做读写分离的中间件我重点看了三个:ProxySQL、MyCAT、ShardingSphere。

维度 ProxySQL MyCAT ShardingSphere
定位 轻量级 MySQL 代理 分布式数据库中间件 生态最全的数据库中间件
部署复杂度 低,单进程 中,依赖 ZooKeeper 高,概念多、配置复杂
读写分离 原生支持,规则灵活 支持 支持
分库分表 不支持 支持 强项
故障自动切换 内置健康检查 需额外部署 需配合其他组件
配置方式 SQL 语句配置 XML 配置 YAML/Java API
性能损耗 很低(C++ 开发) 中等 中等
学习曲线 平缓 中等 陡峭
适合场景 纯读写分离 分库分表 分库分表 + 企业级需求

我当时只需要读写分离,没有分库分表的需求。MyCAT 和 ShardingSphere 功能太重,为了一个读写分离引入一套复杂架构,成本和收益不成正比。ProxySQL 轻量、专注、性能好,够用就行。

当然,如果你已经在用 ShardingSphere 做分库分表,直接用它做读写分离也顺理成章。选型没有绝对对错,看现状。


三、ProxySQL 核心概念

动手之前,先搞清楚几个核心概念,不然配置的时候会一脸懵。

3.1 三层配置体系

ProxySQL 的配置分三层,这是最容易搞混的地方:

┌─────────────┐
│  RUNTIME    │ ← 正在生效的配置(内存中,最快)
├─────────────┤
│  MEMORY     │ ← 你正在编辑的配置(还没生效)
├─────────────┤
│  DISK       │ ← 持久化到 SQLite 的配置(重启不丢)
└─────────────┘

操作逻辑:改 MEMORY → LOAD 到 RUNTIME → SAVE 到 DISK

刚开始我老是忘了 SAVE,重启 ProxySQL 后配置全没了,又得重新配一遍 😭

3.2 几个关键表

ProxySQL 的配置存在表里,不是配置文件,这点和传统中间件很不一样:

表名 作用
mysql_servers 后端 MySQL 实例(主库、从库都在这登记)
mysql_users 应用连接 ProxySQL 用的账号
mysql_query_rules 核心:定义读写分离规则
mysql_replication_hostgroups 主从组别管理(自动故障切换用)

四、实战:从零搭起来

4.1 Docker 启动

docker run -d \
  --name proxysql \
  -p 6033:6033 \
  -p 6032:6032 \
  proxysql/proxysql:2.5

# 6033 是应用连接端口,6032 是管理端口

连接管理端口,开始配置:

mysql -u admin -padmin -h 127.0.0.1 -P 6032 --prompt='ProxySQL> '

4.2 添加后端 MySQL 实例

-- 添加主库(写节点)
INSERT INTO mysql_servers (hostgroup_id, hostname, port, weight, comment)
VALUES (10, 'mysql-master', 3306, 1000, '主库-写');

-- 添加从库(读节点)
INSERT INTO mysql_servers (hostgroup_id, hostname, port, weight, comment)
VALUES (20, 'mysql-slave1', 3306, 500, '从库1-读');
INSERT INTO mysql_servers (hostgroup_id, hostname, port, weight, comment)
VALUES (20, 'mysql-slave2', 3306, 500, '从库2-读');

-- 加载到 RUNTIME 并持久化
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;

hostgroup_id 是分组用的:10 是写组,20 是读组。权重 weight 决定流量分配比例,两个从库都是 500,流量就是对半分。

4.3 配置应用账号

-- 添加应用连接账号(应用用这个连 ProxySQL)
INSERT INTO mysql_users (username, password, default_hostgroup)
VALUES ('app_user', 'app_pass', 10);

LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;

default_hostgroup=10 的意思是:默认请求都走写组(主库),除非后面的规则明确指定读组。

4.4 核心:配置读写分离规则

这是最关键的一步,规则决定了哪些 SQL 走主库、哪些走从库。

-- 规则1:SELECT 且不在事务中 → 走读组(20)
INSERT INTO mysql_query_rules (rule_id, active, match_digest, destination_hostgroup, apply)
VALUES (1, 1, '^SELECT.*', 20, 1);

-- 规则2:事务中的 SELECT → 要走主库(保证一致性)
INSERT INTO mysql_query_rules (rule_id, active, match_digest, match_pattern, destination_hostgroup, apply)
VALUES (2, 1, '^SELECT.*FOR UPDATE', 10, 1);

-- 规则3:写操作(INSERT/UPDATE/DELETE)→ 走写组(10)
INSERT INTO mysql_query_rules (rule_id, active, match_digest, destination_hostgroup, apply)
VALUES (3, 1, '^(INSERT|UPDATE|DELETE)', 10, 1);

-- 规则4:默认兜底,走写组
INSERT INTO mysql_query_rules (rule_id, active, match_digest, destination_hostgroup, apply)
VALUES (4, 1, '.*', 10, 1);

LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;

规则按 rule_id 从小到大匹配,匹配到就停止。所以顺序很重要:先匹配 SELECT FOR UPDATE(要读主),再匹配普通 SELECT(读从),再匹配写操作,最后兜底走主库。


五、验证效果

应用连接改成 ProxySQL 的地址:

spring:
  datasource:
    url: jdbc:mysql://proxysql:6033/mydb
    username: app_user
    password: app_pass

然后用 stats_mysql_query_digest 表查看路由情况:

SELECT digest_text, sum_time, count_star, hostgroup
FROM stats_mysql_query_digest
ORDER BY count_star DESC
LIMIT 10;

如果看到 SELECT 的 hostgroup 是 20,INSERT/UPDATE 的 hostgroup 是 10,恭喜,读写分离生效了 ✅


六、踩坑实录(血泪史)

💣 坑 1:事务里的读操作被路由到从库

现象:一个事务里先 INSERT 了一条数据,紧接着 SELECT 查出来是空的。

原因:SELECT 被规则匹配到读组,去从库查了,但从库还没同步完这条数据(主从延迟)。

解决:开启事务时,ProxySQL 会自动把所有请求路由到同一个 hostgroup(默认是事务开始的那个)。但我当时没用事务包裹,就出问题了。

正确做法:涉及"写后立即读"的逻辑,要么放事务里,要么在 SQL 前加注释强制走主库:

/* hostgroup=10 */ SELECT * FROM orders WHERE user_id = 123;

💣 坑 2:从库挂了,流量没自动切走

现象:一个从库宕机后,ProxySQL 还在往上面发请求,导致部分查询报错。

原因:没配健康检查,或者检查间隔太长。

解决:用 mysql_replication_hostgroups 表让 ProxySQL 自动管理主从状态:

INSERT INTO mysql_replication_hostgroups (writer_hostgroup, reader_hostgroup, comment)
VALUES (10, 20, '主从自动管理');

LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;

配上之后,从库挂了会自动摘流量,主库挂了会触发切换(配合 MGR 或 Orchestrator 效果更好)。

💣 坑 3:规则写得太宽泛,漏匹配

现象:有些查询没被规则匹配到,全走到了默认的主库,从库闲置。

原因match_digest 用的是正则,^SELECT.* 看起来能匹配所有 SELECT,但如果 SQL 里有换行或者注释,就可能匹配不上。

解决:用 SELECT ... FOR UPDATE 这种明确的模式做精确匹配,普通 SELECT 放最后兜底。规则宁可写细一点,别贪多。

💣 坑 4:忘了 SAVE 到 DISK

现象:重启 ProxySQL 后,所有配置都没了。

解决:每次改完配置,记得 SAVE MYSQL ... TO DISK;。后来我写了个脚本,改完自动 LOAD + SAVE,再也没丢过配置。

💣 坑 5:监控没跟上,出问题了才知道

现象:ProxySQL 本身挂了,应用全连不上,半小时后才被发现。

解决:监控 ProxySQL 的关键指标:

  • ProxySQL_Threadpool_TrxNum:当前事务数
  • mysql_server_ping_errors:后端节点健康状态
  • stats_mysql_connection_pool:连接池使用情况

配合 Prometheus + Grafana,ProxySQL 出问题能秒级告警。


七、总结

选型这件事,说难也难,说简单也简单。

我目前只需要读写分离,没有分库分表的需求。ProxySQL 做不了分库分表,但恰好够用,这就是最合适的选择。

手写代码做读写分离,短期轻松长期痛苦。中间件看似多引入一层,省掉的是后面无限叠加的维护成本。

规则顺序和事务一致性,是读写分离最容易翻车的两个地方。配规则的时候多测几遍,别等上线了再翻车。

👋 我是数据库小学妹,一个用设计师思维学数据库的转行人。你们在读写分离选型上踩过什么坑?


本文基于 ProxySQL 2.5 + MySQL 8.0 环境。不同版本配置略有差异,建议参考官方文档确认参数。

相关文章
|
5天前
|
人工智能 自然语言处理 文字识别
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
Qwen3.7-Max是阿里云百炼面向智能体时代推出的新一代旗舰模型,对标GPT-5.5、Claude Opus 4.7等闭源旗舰。该模型支持百万级token上下文窗口,具备顶级推理能力、多模态搜索与视觉理解增强、流式输出低延迟响应等核心优势,覆盖编程、办公、长周期自主执行等复杂场景。同时支持OpenAI接口兼容,便于系统快速迁移。用户可通过Token Plan团队或节省计划等订阅方式灵活调用,适合企业级高要求场景使用。
2574 8
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
|
13天前
|
人工智能 开发工具 iOS开发
Claude Code 新手完全上手指南:安装、国产模型配置与常用命令全解
Claude Code 是一款运行在终端环境中的 AI 编程助手,能够直接在命令行中完成代码生成、项目分析、文件修改、命令执行、Git 管理等开发全流程工作。它最大的特点是**任务驱动、终端原生、轻量高效、多模型兼容**,无需图形界面、不依赖 IDE 插件,能够深度融入开发者日常工作流。
3435 12
|
15天前
|
Shell API 开发工具
Claude Code 快速上手指南(新手友好版)
AI编程工具卷疯啦!Claude Code凭借任务驱动+终端原生的特性,成了开发者的效率搭子。本文从安装、登录、切换国产模型到常用命令,手把手带新手快速上手,全程避坑,30分钟独立用起来。
3510 25
|
9天前
|
人工智能 Linux BI
国内用 Claude Code 终于不用翻墙了:一行命令搞定,自动接 DeepSeek
JeecgBoot AI专题研究 一键脚本:Claude Code + JeecgBoot Skills + DeepSeek 全平台接入 一行命令装好 Claude Code + JeecgBoot Skills + DeepSeek 接入,无需翻墙使用 Claude Code,支持 Wind
2633 5
国内用 Claude Code 终于不用翻墙了:一行命令搞定,自动接 DeepSeek
|
7天前
|
人工智能 自然语言处理 供应链
|
7天前
|
人工智能 自然语言处理 安全
Claude Code 全攻略:命令大全+三种模式+记忆体系+实战工作流完整手册
Claude Code 是当前最流行的终端级 AI 编程助手,能够直接在命令行中完成代码生成、项目理解、文件修改、命令执行、错误修复等全流程开发工作。它不依赖图形界面、不占用额外资源,却能深度理解项目结构,自动生成规范代码,大幅提升研发效率。
1189 3
|
28天前
|
人工智能 JSON 供应链
畅用7个月无影 JVS Claw |手把手教你把JVS改造成「科研与产业地理情报可视化大师」
LucianaiB分享零成本畅用JVS Claw教程(学生认证享7个月使用权),并开源GeoMind项目——将JVS改造为科研与产业地理情报可视化AI助手,支持飞书文档解析、地理编码与腾讯地图可视化,助力产业关系图谱构建。
23611 15
畅用7个月无影 JVS Claw |手把手教你把JVS改造成「科研与产业地理情报可视化大师」