mysql主从复制中主服务器与从服务器的负载均衡

14次阅读

mysql主从复制本身不提供负载均衡能力,仅实现单向数据同步;读写分离需依赖应用层或proxySQL等中间件实现请求分发与延迟感知、写保护校验。

mysql主从复制中主服务器与从服务器的负载均衡

MySQL 主从复制本身不提供负载均衡能力,它只是单向数据同步机制;要实现读写分离式的负载均衡,必须在应用层或中间件层额外引入调度逻辑。

主从复制的默认行为不包含请求分发

MySQL 原生复制只保证 binlog 从主库(master)传输并重放到从库(slave),所有客户端连接仍需自行决定连哪台实例。MySQL 服务器自身不会主动把 select 请求导到从库、把 INSERT/UPDATE/delete 导到主库。

  • 如果你直接在应用里写死连接 localhost:3306,那永远只打到一台机器上
  • 即使配置了多个 IP,在 dns 或连接字符串里用逗号拼接(如 host1,host2),MySQL 客户端驱动通常也不支持自动读写分离
  • mysqlrouterproxysqlmaxscale 这类中间件才是承担路由职责的组件

常见读写分离中间件选型对比

真正起负载均衡作用的是部署在应用和 MySQL 之间的代理层,它们解析 SQL 类型、维护后端节点状态,并按策略转发:

  • ProxySQL:轻量、热配置、支持 SQL 规则匹配(例如匹配 ^SELECT 就走从库),但需要手动维护 mysql_serversmysql_query_rules
  • MySQL Router:官方出品,集成度高,但仅支持 InnoDB Cluster 场景下的读写分离,对传统主从拓扑支持弱
  • MaxScale:功能全面,支持自动延迟检测、权重轮询,但资源占用略高,配置文件语法较复杂
  • 应用内直连(如 javaShardingSphere-JDBC):不依赖中间件,但耦合度高,升级/调试成本上升

从库延迟导致的负载不均问题

当从库 Seconds_Behind_Master 持续升高时,即使流量被分发过去,查询结果也可能滞后,此时负载均衡反而成了隐患:

  • ProxySQL 可通过 monitor_username 定期执行 SHOW SLAVE STATUS 并根据 Seconds_Behind_Master 动态下线节点
  • MaxScale 默认启用 replication lag threshold,超阈值自动剔除该从库
  • 若用 DNS 轮询或客户端硬编码列表,必须自己实现心跳 + 延迟探测逻辑,否则“均衡”只是假象
SELECT    host,   port,   status,   lag FROM mysql_server_joins  WHERE host = 'slave01' AND lag > 30;

写操作误发到从库会直接报错

从库默认开启 read_only=ON,任何非 super 权限用户尝试执行写语句都会收到错误:

ERROR 1290 (HY000): The MySQL server is running with the --read-only option so it cannot execute this statement

这意味着——

  • 如果中间件未正确识别事务边界或未拦截 BEGIN/COMMIT,可能导致部分写请求落到从库并失败
  • 某些 ORM(如 Django)在事务中混用读写,需确保中间件支持会话一致性(sticky session)或显式指定 using='default'
  • 不要关闭从库的 read_only 来“兼容”,这会让数据不一致风险失控

真正的负载均衡不在复制协议里,而在你如何把请求导向正确的节点;而最常被忽略的,是延迟感知和写保护这两层校验是否真正生效。

text=ZqhQzanResources