Nginx利用TCP代理实现Redis集群高可用转发

1次阅读

nginx stream模块可作为redis集群四层负载均衡器实现高可用转发,但仅支持TCP连通性健康检查且不解析Redis协议,客户端仍需处理ASK/MOVED重定向。

Nginx利用TCP代理实现Redis集群高可用转发

Redis集群本身不提供统一入口,客户端需直连多个节点,难以实现故障自动转移。Nginx 1.9+ 支持 stream 模块(TCP/udp 代理),可作为四层负载均衡器,将客户端请求透明转发至 Redis 集群的可用节点,配合健康检查,达到高可用转发效果。

前提条件:启用 Nginx stream 模块并配置基础 TCP 代理

Nginx 默认不编译 stream 模块,需确认已启用:

  • 执行 nginx -V 2>&1 | grep -o with-stream,输出含 with-stream 表示支持
  • 若无,需重新编译 Nginx 并添加 --with-stream 参数
  • 在主配置文件(如 nginx.conf)顶层添加 stream { ... } 块,不可放在 http

配置 Redis 节点上游与健康检查

stream 模块原生不支持 HTTP 类健康检查,但可通过 health_check 指令配合 TCP 连通性探测(默认仅检查端口可达):

  • 定义 upstream,指定 Redis 节点 IP 和端口(如 6379)
  • 启用 health_check,可设置间隔(interval=3s)、超时(timeout=1s)、失败阈值(fails=3)和恢复阈值(passes=2
  • 注意:该检查仅验证 TCP 握手成功,无法判断 Redis 实例是否真正可服务(如 OOM、只读状态等),生产环境建议搭配外部脚本或 consul 等做更深层探活

示例配置片段:

stream {     upstream redis_cluster {         server 10.0.1.10:6379 max_fails=3 fail_timeout=30s;         server 10.0.1.11:6379 max_fails=3 fail_timeout=30s;         server 10.0.1.12:6379 max_fails=3 fail_timeout=30s;         health_check interval=3s timeout=1s fails=3 passes=2;     }      server {         listen 6380;         proxy_pass redis_cluster;         proxy_timeout 1s;         proxy_responses 1;     } }

关键注意事项与局限性

使用 Nginx 做 Redis TCP 代理并非万能方案,需正视其边界:

  • 不解析 Redis 协议:Nginx 仅做字节流转发,无法识别 ASK/MOVED 重定向响应,客户端仍需自行处理集群拓扑变更(即仍要走 Smart Client 模式)
  • 连接粒度负载均衡:每个 TCP 连接固定绑定到一个 upstream server,不支持单请求级分发;长连接场景下,负载可能不均
  • 无密码透传限制:若 Redis 启用 requirepass,客户端认证凭据会原样转发,Nginx 不参与鉴权;确保后端节点密码一致,或前置统一认证网关
  • 不支持 Pipeline 批量指令的细粒度容错:某条命令失败不影响后续,但整个连接异常会导致批量中断

替代或增强方案建议

若需更贴近 Redis 集群语义的代理能力,可考虑:

  • Twemproxy(Nutcracker):专为 Redis/memcached 设计,支持一致性哈希、自动重试、部分协议感知(如忽略 INFO 响应)
  • Redis Proxy(如 Predixy、Redis-Cluster-Proxy):支持完整集群协议解析、ASK/MOVED 自动重定向、线程、连接池等特性
  • Service Mesh(如 istio + Envoy):通过扩展过滤器支持 Redis 协议解析与路由,适合云原生架构,但复杂度高

单纯希望快速落地轻量级接入层且能接受客户端保持集群逻辑时,Nginx stream 是简洁可行的选择。

text=ZqhQzanResources