mysql主从复制≠负载均衡,因它仅同步数据而不分发请求;读写分离与负载均衡需proxysql等中间件或客户端配置实现,且须正确设置权重、主从组、健康检测及强一致性读策略。

MySQL 主从复制本身不能实现负载均衡,它只是数据同步机制,不参与连接分发、健康检查或权重调度。
为什么主从复制 ≠ 负载均衡
主从复制只保证从库有主库的副本数据,但不会自动把读请求分到多个从库,也不会判断哪个从库延迟低、是否存活。写请求必须走主库,读请求发给谁——这个决策 MySQL Server 层完全不管。常见误解是“一主多从就能自动分担读压力”,实际中如果没上层组件,所有读请求仍可能打在同一个从库甚至主库上。
-
SELECT语句不会被 MySQL 自动路由到从库;应用不显式连从库,就读不到从库 -
Seconds_Behind_Master为 0 不代表实时——GTID + 多线程复制下该值可能长期不准 - 从库宕机后,主从复制链路依然“看起来正常”,但读请求会失败,MySQL 不会自动剔除节点
ProxySQL 是最实用的读写分离+负载均衡方案
它运行在应用和 MySQL 之间,通过配置规则做连接级路由,并支持实时健康检测。关键配置点必须到位,否则读写分离和负载均衡都会失效:
- 必须在
mysql_servers表里给每个从库显式设置weight,默认都是 1,无法体现真实负载能力差异 - 必须用
mysql_replication_hostgroups明确划分writer_hostgroup和reader_hostgroup,否则SELECT还是走主库 -
monitor模块要启用,且mysql-monitor_username必须在所有后端实例上有REPLICATION CLIENT权限,否则延迟检测失效 - 不要只依赖
max_replication_lag判断从库可用性;建议配合ping_interval_ms+ping_timeout_server_ms做连通性探测
Java 应用直连多从库时,mysql-connector-j 的 loadBalance 模式容易误用
它靠客户端轮询分发连接,不感知数据库状态,也不做 SQL 级别读写识别,典型问题包括:
- URL 中漏掉
loadBalanceStrategy=roundrobin参数,会导致 fallback 到第一个 host(host1),读流量全压单点 - 必须调用
connection.setReadOnly(true),驱动才启用负载均衡;很多 ORM(如 MyBatis、Hibernate)默认不设只读,结果所有读都走host1 - 从库挂了不会自动摘除,下次新建连接仍会尝试连接已宕机节点,需配合
loadBalanceAutoCommitStatementThreshold和重试逻辑 - 不支持事务内强制读主库,
BEGIN; SELECT ...; INSERT ...; COMMIT;中的SELECT可能落到从库,造成刚写完就读不到
“刚写完立刻读”场景必须业务层兜底
这是最容易被忽略的一致性风险点。例如用户注册后跳转个人页,此时从库可能尚未同步新记录。ProxySQL 或客户端驱动都无法自动识别这种上下文关联。
- 不能依赖“写后立即读从库”来降低主库压力,除非业务允许最终一致性
- 强一致性读(比如注册后查自己信息)应显式走主库,可通过自定义注解、ThreadLocal 标记或 SQL Hint 实现
- 如果用了
SET SESSION TRANSACTION READ ONLY,注意它不等价于setReadOnly(true),驱动不识别该语句











