ProxySQL 全景解读

ProxySQL 全景解读

定义

ProxySQL 是 MySQL 协议级的高性能中间代理,位于应用与 MySQL 实例之间,对 SQL 流量做透明路由、负载均衡、缓存、限流、审计、故障转移 等操作。


1. 诞生背景

  • 传统痛点
    • 主从读写分离需要在业务里维护多套连接串。
    • 单实例故障导致连接雪崩。
    • DBA 想灰度上线、在线切换、SQL 审计,但业务代码改不动。
  • 早期方案:MySQL Proxy(已停滞)、Atlas、Cobar 等,功能或性能总差一点。
  • 2015 年:ProxySQL 以 C++11 重写,主打 “零侵入、热加载、高并发”

2. 核心功能

功能 一句话解释 典型场景
读写分离 按正则/Schema/注释路由到不同 hostgroup 主写从读
负载均衡 权重、最少连接、响应时间、复制延迟感知 多从库分摊读
连接池 与后端维持少量长连接,前端可并发上万 高并发短连接
查询缓存 TTL + 哈希缓存,自动失效 报表、字典表
故障探测 心跳、复制延迟、GTID、只读状态 故障自动剔出
在线重载 修改配置无需重启,毫秒级生效 灰度变更
审计 & 限流 正则匹配、用户级、SQL 级黑名单 防慢查询打爆
防火墙 基于规则集的 SQL 注入防御 安全合规

3. 架构速览

┌────────────┐     ┌─────────────┐     ┌────────────┐
│   App      │────▶│  ProxySQL   │────▶│ MySQL (R/W)│
└────────────┘     │  (6033)     │     └────────────┘
                   │  Admin      │
                   │  (6032)     │
                   └─────────────┘
  • 6033 业务端口,兼容 MySQL 协议,客户端无感知。
  • 6032 管理端口,SQL 接口,支持 SELECT/UPDATE/INSERT 改配置。
  • 多层表
    • mysql_servers 后端列表
    • mysql_users 账号映射
    • mysql_query_rules 路由规则
    • runtime_* 实时生效,disk 层持久化,config file 仅启动加载。

4. 优势总结

  1. 性能
    • 单核可达 50w QPS(官方基准)。
    • epoll + 多线程,CPU 亲和,零拷贝转发。
  2. 零侵入
    • 不改一行代码即可实现读写分离、连接池。
  3. 热加载
    • 规则修改 LOAD ... TO RUNTIME; SAVE ... TO DISK; 毫秒级生效。
  4. 细粒度路由
    • 支持正则、Schema、用户、事务状态、注释、prepare 语句。
  5. 高可用
    • 支持 ProxySQL Cluster(v2.0+),多实例配置同步。
  6. 生态
    • Prometheus exporter、Orchestrator、Percona Toolkit 等工具链完善。
    • 与 K8s Operator(如 prpxysql-operator)深度集成。

5. 劣势 & 挑战

维度 问题 缓解方案
学习曲线 20+ 张系统表,新手易迷路 官方文档 + 官方镜像沙箱
单点故障 早期无集群 2.x 原生 Cluster + VIP/Keepalived
资源消耗 高并发 CPU 占满 多实例 + NUMA 绑定
延迟 多一跳,平均 +0.2 ms 同机房部署、开启 fast_forward
复杂查询 大事务、prepare 语句规则难写 渐进式灰度、先跑监控
版本升级 1.x → 2.x 有表结构变化 官方升级脚本 + 双实例并行

6. 与同类方案对比

特性 ProxySQL MySQL Router MaxScale Atlas
协议层 MySQL MySQL MySQL + Binlog MySQL
读写分离 ✅ 正则/规则 ✅ 基础 ✅ 高级 ✅ 基础
连接池 ✅ 内核
查询缓存 ✅ TTL
审计/限流 ✅ SQL 级
开源协议 GPL-3.0 GPL-2.0 BSL 1.1 GPL-2.0
性能

7. 典型落地场景

场景 架构要点
K8s 微服务 每个 Namespace 部署一组 ProxySQL StatefulSet,Service 暴露 6033,ConfigMap 注入规则。
SaaS 多租户 按租户维度建 hostgroup,mysql_query_rules 里根据 schemaname 路由到不同实例。
金融级高可用 两机房三实例集群 + Orchestrator 自动主从切换 + ProxySQL 故障探测,RTO < 30s。
实时报表 报表 SQL 命中 query_cache,缓存 60s,QPS 提升 5 倍,后端 CPU 下降 70%。

8. 总结

ProxySQL 是一把 “瑞士军刀”,把 DBA 的日常痛点(读写分离、故障转移、SQL 审计)都做成 可热插拔的规则表,让 开发和运维第一次有了共同语言
当你犹豫要不要在代码里写多个数据源时,先想想:

“能不能交给 ProxySQL 一行配置解决?”


延伸阅读

常用命令

下面是 “常用 ProxySQL 管理命令速查表”,全部基于 6032 管理端口 的 SQL 语法。


1. 连上管理接口

mysql -uadmin -padmin -h127.0.0.1 -P6032 --prompt='ProxySQL> '

2. 后端 MySQL 实例

目的 命令
查看所有节点 SELECT hostgroup_id,hostname,port,status,weight FROM mysql_servers;
临时上线 / 下线 UPDATE mysql_servers SET status='OFFLINE_SOFT' WHERE hostname='10.0.0.2';
永久新增节点 INSERT INTO mysql_servers(hostgroup_id,hostname,port) VALUES (10,'10.0.0.5',3306);
立即生效 LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;

3. 用户与权限

目的 命令
查看用户 SELECT username,password,default_hostgroup FROM mysql_users;
新增业务用户 INSERT INTO mysql_users(username,password,default_hostgroup) VALUES ('app','app_pwd',10);
立即生效 LOAD MYSQL USERS TO RUNTIME; SAVE MYSQL USERS TO DISK;

4. 路由规则

目的 命令
查看规则 SELECT rule_id,match_pattern,destination_hostgroup,apply FROM mysql_query_rules ORDER BY rule_id;
按正则路由 INSERT INTO mysql_query_rules(rule_id,active,match_pattern,destination_hostgroup,apply) VALUES (100,1,'^SELECT.*FOR UPDATE',10,1);
按注释路由 INSERT INTO mysql_query_rules(active,match_pattern,destination_hostgroup) VALUES (1,'/\*master\*/',10);
立即生效 LOAD MYSQL QUERY RULES TO RUNTIME; SAVE MYSQL QUERY RULES TO DISK;

5. 连接池 & 变量

目的 命令
查看全局变量 SELECT * FROM global_variables WHERE variable_name LIKE '%threads%';
动态修改变量 SET mysql-max_connections=3000;
立即生效 LOAD MYSQL VARIABLES TO RUNTIME; SAVE MYSQL VARIABLES TO DISK;

6. 监控 & 健康检查

目的 命令
查看心跳日志 SELECT hostname,ping_error,ping_time FROM monitor.mysql_server_ping_log ORDER BY time_start_us DESC LIMIT 10;
查看复制延迟 SELECT hostname,repl_lag FROM monitor.mysql_server_replication_lag_log ORDER BY time_start_us DESC LIMIT 10;
立即重试 UPDATE mysql_servers SET status='ONLINE' WHERE hostname='10.0.0.3';

7. 统计 & 性能

目的 命令
实时 QPS SELECT SUM(Queries) AS total_qps FROM stats_mysql_global;
Top 慢查询 SELECT hostgroup,username,digest_text,sum_time,count_star FROM stats_mysql_query_digest ORDER BY sum_time DESC LIMIT 10;
连接池使用率 SELECT hostgroup,srv_host,ConnUsed,ConnFree,ConnOK FROM stats_mysql_connection_pool;

8. 缓存

目的 命令
查看缓存条目 SELECT count(*) FROM stats_mysql_query_cache;
清空缓存 SELECT * FROM stats_mysql_query_cache_reset;

9. 集群(v2.x)

目的 命令
查看集群节点 SELECT hostname,checksum,epoch FROM runtime_proxysql_servers;
手动同步配置 LOAD ... FROM DISK; LOAD ... TO RUNTIME; (所有节点执行)

10. 一键“三板斧”

在任何一台 ProxySQL 节点上执行,即可把 内存 → 运行 → 磁盘 全部保存:

SAVE MYSQL VARIABLES     TO DISK;
SAVE MYSQL USERS         TO DISK;
SAVE MYSQL SERVERS       TO DISK;
SAVE MYSQL QUERY RULES   TO DISK;
SAVE ADMIN VARIABLES     TO DISK;

11. 最常用 10 条速记

场景 一句话命令
连管理 mysql -uadmin -padmin -P6032
看后端 SELECT * FROM mysql_servers;
看用户 SELECT * FROM mysql_users;
看路由 SELECT * FROM mysql_query_rules;
看变量 SHOW VARIABLES LIKE '%threads%';
看 QPS SHOW MYSQL STATUS LIKE 'Questions';
看 Top SQL SELECT * FROM stats_mysql_query_digest ORDER BY sum_time DESC LIMIT 5;
下线节点 UPDATE mysql_servers SET status='OFFLINE_SOFT' WHERE hostname='x'; LOAD MYSQL SERVERS TO RUNTIME;
加用户 INSERT INTO mysql_users(...) VALUES (...); LOAD MYSQL USERS TO RUNTIME;
加规则 INSERT INTO mysql_query_rules(...) VALUES (...); LOAD MYSQL QUERY RULES TO RUNTIME;

把这张表贴到 ~/.my.cnf 旁,效率立刻 +200%。
如需图形化,可对接 ProxySQL Admin Web UIPercona PMM

posted @ 2025-08-24 17:45  元贞  阅读(85)  评论(0)    收藏  举报