mysql读写分离集群需三层协同:先通过gtid+半同步确保主从数据强一致,再用proxysql按sql类型智能路由读写请求并剔除延迟从库,最后结合权重调度、动态监控与proxysql双实例高可用实现高效负载均衡。

搭建 MySQL 读写分离集群实现高效负载均衡,关键在于三层协同:稳定的数据同步、智能的请求路由、可靠的故障应对。不依赖单一工具,而是按阶段推进——先确保主从数据一致,再用中间件自动分流读写,最后通过健康检查和权重策略让读请求真正“均衡”起来。
一、主从复制必须稳且可控
读写分离的前提是数据能及时、准确地从主库同步到从库。光配好 server-id 和 log-bin 不够,还要关注实际同步质量:
- 使用 GTID 模式(而非传统 file+pos),避免因日志轮转或跳过事件导致复制中断;开启方式:
gtid_mode=ON+enforce_gtid_consistency=ON - 推荐启用 半同步复制(
rpl_semi_sync_master_enabled=1),保证至少一个从库落盘后再返回客户端,降低主库宕机时的数据丢失风险 - 定期检查
Seconds_Behind_Master,但更要看Retrieved_Gtid_Set和Executed_Gtid_Set是否一致——延迟数值可能误报,GTID 才是真实同步状态 - 从库务必设置
read_only=ON,并限制超级用户权限(如撤销SUPER权限),防止意外写入破坏一致性
二、用 ProxySQL 实现细粒度读写分流
比起简单轮询或应用层硬编码,ProxySQL 能在协议层解析 SQL 并动态路由,兼顾透明性与灵活性:
- 将主库加入 hostgroup 10(写组),从库加入 hostgroup 20(读组),并在配置中明确标注权重(例如
weight=3的高性能从库承担更多流量) - 配置两条核心路由规则:
^SELECT.*FOR UPDATE$→ 强制走主库(避免分布式事务脏读)^SELECT→ 默认走读组,配合apply=1确保匹配优先级 - 开启 连接池(
mysql-pool_idle_timeout=60)和 查询缓存(对不变的配置类 SELECT 有效),减少后端连接压力 - 通过
mysql_servers表的max_replication_lag字段自动剔除延迟超阈值(如 5 秒)的从库,避免把请求打到“假活”节点
三、负载均衡不是平均分配,而是按需调度
真正的“高效均衡”,不是让每个从库处理相同请求数,而是让它们在各自能力范围内分担合理负载:
- 在 ProxySQL 中启用 least_used 或 connection_pool 调度算法,比简单轮询更能适应瞬时连接数差异
- 为不同从库设置不同
weight值(如 192.168.1.10:3306?weight=5,192.168.1.11:3306?weight=2),匹配其硬件规格或网络带宽 - 对慢查询多的业务模块(如报表导出),可单独建一个低权重、高 buffer 的专用从库,并通过 SQL 注释
/*+ USE_SLAVE_2 */绑定路由规则 - 配合 Prometheus + Grafana 监控各从库的
Threads_running、Innodb_buffer_pool_read_requests等指标,动态调整权重而非固定配置
四、高可用不能只靠“自动切换”
主库故障时,光靠中间件摘除节点不够——要确保服务不中断、数据不丢、切换后仍可读写:
- ProxySQL 自身应部署双实例 + Keepalived VIP,避免代理层单点;配置
mysql-monitor_username启用心跳检测,间隔建议 ≤3 秒 - 主库宕机后,需触发外部脚本(如调用 Orchestrator API 或手动 promote)选出新主,并更新 ProxySQL 的 hostgroup 映射——不能仅靠“读组里没主就报错”
- 切换完成后,强制刷新 ProxySQL 查询规则缓存(
LOAD MYSQL QUERY RULES TO RUNTIME),防止旧路由规则残留 - 所有写操作客户端应具备重试机制(如 retry on “Lost connection”),配合应用层幂等设计,掩盖短暂切换窗口











