Nginx通过stream模块可实现MySQL/Redis四层负载均衡:需编译启用--with-stream、配置置于http块外;MySQL须设proxy_responses 1和长超时;Redis推荐ip_hash保障连接一致性。

要用 Nginx 实现 MySQL 和 Redis 的四层负载均衡,核心是启用并正确配置 stream 模块——它不解析 SQL 或 RESP 协议,只做原始 TCP 连接转发,低延迟、高吞吐,适合数据库类长连接场景。
确认并启用 stream 模块
stream 模块从 Nginx 1.9.0 起支持,但默认不编译进二进制。执行以下命令验证:
nginx -V 2>&1 | grep -o with-stream
若无输出,需重新编译,关键参数包括:
-
--with-stream(必需) -
--with-stream_ssl_module(如需 TLS 透传) - 主流包管理器(apt/yum)安装的 Nginx 通常不含该模块,建议源码编译或选用含 stream 的第三方构建版
主配置文件顶部必须显式加载模块:
load_module modules/ngx_stream_core_module.so;
且 stream { ... } 块须与 http { ... } 同级,不可嵌套在 http 内。
MySQL 四层代理关键配置
MySQL 是二进制协议、握手敏感、长连接密集型服务,配置需兼顾稳定性与健康感知:
-
proxy_responses 1:等待首个响应包(如 greeting packet)再判定连接成功,避免仅靠 TCP 握手误判后端可用 -
proxy_timeout 1h:匹配 MySQL 默认wait_timeout=28800,防止 Nginx 主动断开空闲连接 -
proxy_buffer_size 512k:防止mysqldump或大结果集触发缓冲区截断 -
so_keepalive on和proxy_socket_keepalive on:减少中间网络设备或防火墙导致的连接中断 - 后端节点用
backup标记可实现故障自动切换,例如主库异常时流量切至从库(注意:stream 不支持读写分离,SQL 层路由需 ProxySQL 等中间件)
Redis 四层代理注意事项
Redis 协议简单但对连接粘性与命令原子性敏感,尤其在 pipeline 和事务场景下:
- 禁用 PROXY 协议:
proxy_protocol off(除非后端明确支持),避免客户端兼容问题 - 推荐使用
ip_hash或least_conn:保障同一客户端 IP 或连接数最少的节点持续承接请求,避免请求分散破坏 pipeline 语义 - 密码和 DB 选择由客户端直传后端,Nginx 不参与鉴权,务必确保所有后端 Redis 实例
requirepass和默认SELECTdb 一致 - 不适用于原生 Redis Cluster:Nginx 无法识别
MOVED/ASK重定向,客户端必须自行处理集群拓扑;可前置用于哨兵模式主节点统一入口,但需配合外部脚本动态更新 upstream
通用避坑与优化要点
看似简单的四层代理,几个细节极易引发连接失败或静默失效:
- 监听端口不能被占用(如 MySQL 3306、Redis 6379),部署前用
ss -tlnp | grep :3306检查 - 防火墙需放行 Nginx 监听端口,以及 Nginx 到后端服务器的出向连接(如 3306/6379)
- 配置中漏掉分号、缩进错误或把 stream 块写进 http 块内,Nginx 不报语法错误,但配置会静默失效
- 开源版 Nginx 不支持 stream 原生
health_check指令(仅 Plus 版),可用max_fails/fail_timeout做被动探活,或结合外部脚本 + reload 实现主动健康检查


















