读写分离后,负载均衡策略的核心是把读流量分摊到多个从库节点,把写流量锁定到主库单点,并通过健康检查把故障节点摘除。 如果只做读写分离而不配置负载均衡,读请求仍可能全部压到单台从库,主库写入造成的延迟扩散无法被有效吸收。
读写分离后负载均衡怎么配置:四步落地
给读库集群挂载内网负载均衡
读库通常有多台,常见做法是创建一个内网负载均衡实例,监听数据库端口,把多台从库挂到同一个后端服务组,云负载均衡监听器可配置TCP或HTTP,但MySQL/PostgreSQL等数据库走TCP协议,因此选择四层TCP监听,不要选七层HTTP,后端端口填从库实际端口,例如3306,权重按机器配置分配。
读请求进入负载均衡后,会按调度算法分发到不同从库,常见的调度算法有三种:轮询、最小连接数、源IP哈希,读库之间配置相近时用轮询,配置差异明显时用权重轮询,有会话依赖的读查询用源IP哈希,能把同一客户端固定到同一从库,减少连接切换成本。
写流量固定指向主库,不参与轮询
写请求必须落在主库,负载均衡层不能把写库也放进普通轮询池,否则写入会分发到从库导致数据不一致,应用连接串中,写数据源直接填主库内网地址,读数据源填负载均衡VIP,这样写路径不走负载均衡,读路径走负载均衡,两边互不干扰。
如果应用使用单数据源配置,需要把代码里的读写逻辑拆开,或者在数据访问层封装两个连接池,这个改动通常比想象中小,但必须做,写连接池只绑定主库IP,读连接池只绑定负载均衡VIP,两个连接池的参数可以独立调整,例如读连接池最大连接数调大,写连接池保持较小值。
在代理层做读写判断
如果应用不能改代码区分读写,需要引入数据库中间件或代理,例如MyCat、ShardingSphere-Proxy、ProxySQL、MaxScale,代理层监听一个统一端口,应用只连代理,由代理把SELECT转发到读库负载均衡VIP,把INSERT/UPDATE/DELETE转发到主库,负载均衡放在代理和从库之间,避免代理成为读流量的单点。
代理层做读写判断的好处是应用无感,但也带来代理本身的高可用问题,生产环境中代理要部署至少两台,前面再用负载均衡或虚拟IP做故障转移,代理配置里需要写清读库负载均衡VIP和主库内网地址,同时开启后端健康检查,否则代理会把请求发给已经宕机的读库。
配置健康检查与故障切换
健康检查不能用普通TCP端口探测,因为端口活着不代表从库能正常服务,云负载均衡通常支持自定义健康检查,可配置检查路径或检查命令,对MySQL从库,建议在从库上放一个心跳表或使用mysqladmin ping结果作为判定,健康检查间隔可设3-5秒,连续失败2-3次后自动摘除节点,恢复后重新挂入。
故障切换分两层:读库故障时负载均衡自动摘除,写库故障时需要手动或半自动提升从库为主库,负载均衡只负责读流量切换,不负责主从切换,主库宕机后,需要先将一台从库提升为主库,再修改应用写连接地址,同时确认其余从库重新指向新的主库。
主从复制和读写分离的区别:决定负载均衡边界
主从复制解决数据同步,读写分离解决流量分发
两者经常被混在一起。主从复制

是把主库的binlog重放到从库,保证数据副本一致,它不关心请求怎么分配。读写分离是把读请求和写请求拆开,写请求只走主库,读请求走从库,负载均衡属于读写分离的流量分发层,不是主从复制的功能。
配置负载均衡前,必须确认主从复制已经正常工作,验证方法是登录从库执行SHOW SLAVE STATUS,查看Slave_IO_Running和Slave_SQL_Running是否都为Yes,同时Seconds_Behind_Master保持稳定,如果复制链路断了,从库数据会越来越旧,负载均衡把读流量导过来只会放大错误。
负载均衡不能替代主从复制
如果把写请求错发到从库,而应用又读到该从库,会出现数据“丢失”假象,根因是主从复制存在延迟,从库数据落后于主库,负载均衡配置必须基于主从复制正常工作的前提,否则读请求会读到旧数据,配置时先把从库的Seconds_Behind_Master纳入监控,延迟过高的从库可临时从负载均衡后端摘除。
主从延迟是读写分离架构里的老问题,延迟原因包括大事务、批量写入、从库硬件弱、网络抖动,负载均衡只能把流量从延迟高的从库切走,不能消除延迟本身,解决延迟要另找原因,比如拆分大事务、增加从库配置、优化并行复制参数。
为什么负载均衡位置要放在从库侧
主从复制和读写分离的区别决定了负载均衡边界:主库只有一个,不需要负载均衡;从库有多个,才需要负载均衡把读流量摊开,因此负载均衡VIP一般只绑定从库,主库保持独立IP,应用写连接直接连主库。
有人会把主库和从库都加入负载均衡后端,再靠权重把写请求固定到主库,这种方案看似统一,实际上风险很高,一旦主库权重被误改,或者健康检查误摘除主库,写入就会漂移到从库,引发数据错乱,生产上不建议把主库放进读负载均衡池。
高并发场景下读写分离负载均衡方案:三种架构横向对比
应用直连负载均衡VIP
最简单,应用代码里配置两个数据源:读数据源指向负载均衡VIP,写数据源指向主库,适合轻量业务,优点是链路短,缺点是每个应用实例都要配置、切换逻辑分散,高并发时应用侧连接池要调大,否则读请求会在连接池排队。
这个方案对DBA友好,因为数据库侧边界清晰,排查问题容易,但应用开发要理解读写分离逻辑,不能把所有SQL都走默认数据源,很多框架支持多数据源注解,例如Spring中的@ReadOnlyDataSource思路,但具体名称以框架为准。
代理层统一接入
在应用和数据库之间加一层代理,应用只连代理地址,代理识别SQL类型,自动转发,适合高并发场景下读写分离负载均衡方案中需要透明切换、连接复用的业务,缺点是代理本身要集群部署,需要额外运维。
代理层可以做到连接复用,把大量短连接合并成少量长连接打到后端数据库,减轻数据库连接数压力,负载均衡依然放在代理和从库之间,代理把读流量发给负载均衡VIP,代理集群自身可以再用云负载均衡做一个入口,形成双层负载结构。
云数据库自带读写分离地址
云厂商RDS提供读写分离地址,自带负载均衡和权重分配,应用只连这个地址,写入自动路由主实例,读请求按权重分发到只读实例,这种方案省去自己搭建负载均衡,但灵活性受云平台功能限制,云负载均衡按量付费价格通常按实例费加处理能力费用计算,需要根据并发连接数估算。

云数据库读写分离地址一般支持延迟阈值控制,只读实例延迟过高时会自动暂停读流量分发,这对运维来说省心不少,但成本和功能绑定在云平台,无法迁移到自建环境,选择前要对比自建代理和云托管方案的总成本。
| 对比项 | 应用直连负载均衡 | 代理层统一接入 | 云数据库读写分离地址 |
|---|---|---|---|
| 接入难度 | 低 | 中 | 低 |
| 读写判断位置 | 应用代码 | 代理SQL解析 | 云平台自动 |
| 连接复用 | 一般 | 好 | 好 |
| 故障切换速度 | 依赖负载均衡 | 依赖代理集群 | 平台托管 |
| 运维复杂度 | 低 | 中 | 低 |
云负载均衡按量付费价格与地域部署注意点
价格构成
云负载均衡按量付费价格通常包含实例费和流量/LCU费两部分,实例费按小时或天结算,LCU根据并发连接数、每秒新建连接数和流量换算,不同厂商计费口径不同,创建前应在控制台用“费用计算器”按实际并发量模拟,不要只关注实例费,高并发下LCU费用可能超过实例费。
数据库读写分离的内网负载均衡,流量走内网,通常没有公网流量费,LCU消耗取决于读请求每秒新建连接数,不是总连接数,如果应用侧连接池足够大,连接复用高,LCU消耗会低很多,短连接频繁建立会推高LCU用量,这点在压测时容易被忽略。
地域部署
读写分离集群如果主库部署在华东地域,从库建议部署在同一地域的可用区,负载均衡实例也选同一地域,跨地域访问延迟会放大主从延迟,还会产生额外公网流量费用。同一地域内可用区之间使用内网互通,延迟通常在毫秒级,适合做读写分离。
负载均衡实例和后端从库必须在同一地域,这是云平台的硬性限制,主库和从库可以跨可用区,但不建议跨地域做实时复制,跨地域复制一般用于容灾,不适合承担日常读流量,否则延迟和带宽成本都会上升。
负载均衡实例与后端从库的绑定
云负载均衡后端服务器组添加从库时,使用内网IP,不要用公网IP,否则流量会绕出公网,既慢又贵,内网负载均衡不收取公网流量费,这也是控制成本的关键,添加后端后,要检查安全组或防火墙规则,确保负载均衡实例的探测流量能到达从库端口。
有些云厂商要求后端服务器和负载均衡实例属于同一VPC,跨VPC需要额外配置对等连接或私有链接,规划网络时,把数据库和负载均衡放在同一VPC内的不同子网,可以避免很多连通性问题。
实操配置示例:Nginx四层代理与云负载均衡监听器
Nginx四层TCP代理配置
如果自建环境用Nginx做读库负载均衡,使用stream模块,不要用http模块,配置示例如下:
stream { upstream mysql_read { server 10.0.1.11:3306 weight=3; server 10.0.1.12:3306 weight=2; server 10.0.1.13:3306 backup; } server { listen 3307; proxy_pass mysql_read; proxy_connect_timeout 3s; } }
weight按从库硬件配置调整,backup表示其他从库都不可用时才启用,注意Nginx的stream健康检查需要商业版或第三方模块,社区版只能通过TCP握手判断端口存活,对数据库来说,端口存活不等于服务可用,所以Nginx社区版不适合直接做数据库负载均衡的健康检查,需要配合外部脚本或换成HAProxy。
云负载均衡监听器转发规则
以主流云厂商控制台为例,操作路径为:负载均衡实例 → 监听器管理 → 创建TCP监听器 → 监听端口填3306 → 选择后端服务器组 → 添加从库内网IP和端口,转发规则中,默认调度算法可选轮询、最小连接数、源IP哈希,数据库读请求如果对会话有依赖,选源IP哈希可把同一客户端请求固定到同一从库,减少连接切换。
创建监听器时还要配置健康检查,健康检查协议和监听协议一致,检查端口默认等于后端端口,也可以单独指定,检查间隔调短可以更快发现故障,但会增加从库探测压力,一般检查间隔3秒、超时2秒、连续失败2次摘除,是多数运维可接受的折中。
HAProxy配置片段
HAProxy更适合数据库负载均衡,支持MySQL健康检查:
listen mysql_read
bind 10.0.0.5:3306
mode tcp
balance roundrobin
option mysql-check user haproxy_check
server slave1 10.0.1.11:3306 check inter 3s fall 2 rise 1
server slave2 10.0.1.12:3306 check inter 3s fall 2 rise 1
option mysql-check会模拟MySQL握手验证账号可用性,比单纯TCP探测准确。inter 3s fall 2 rise 1表示每3秒检查一次,连续失败2次摘除,成功1次重新上线。haproxy_check账号需要在每个从库上提前创建,只授予最小权限即可,不要用业务账号做健康检查。
读写分离后的负载均衡不是把主库和从库一起扔进轮询池,而是读集群做负载、写主库做单点,配置顺序上,先保证主从复制延迟可控,再挂载读库负载均衡,最后通过健康检查和权重把读流量压到不同从库,这样能把读写分离的收益最大化,避免延迟和误转发造成数据问题。
Q&A
读写分离后负载均衡怎么配置才能避免主从延迟影响?
把从库的Seconds_Behind_Master监控做成摘除条件,延迟超过阈值时将该从库从负载均衡后端移除,同时应用读连接改用负载均衡VIP后会自动切到其他从库,阈值可设为几十秒,具体根据业务容忍度调整,延迟恢复后再把从库重新加入后端服务器组。
主从复制和读写分离的区别会影响负载均衡选择吗?
会影响,主从复制只管数据同步,不能作为流量入口,读写分离需要负载均衡或代理判断读写,因此选择负载均衡时,要确认它支持数据库端口四层转发,而不是只支持HTTP七层转发,同时健康检查要能识别数据库服务状态,不能只探测TCP端口。
云负载均衡按量付费价格到底怎么算?
按量付费通常按实例规格和LCU计量,不同云厂商对LCU的换算不同,创建负载均衡前,在控制台计费说明页查看当前地域的单价,按并发连接数和每秒新建连接数估算,内网负载均衡通常没有公网流量费用,数据库读写分离场景应优先选择内网实例。
