Nginx实现一致性哈希负载均衡需启用ngx_http_upstream_hash_module模块并使用hash $key consistent语法;不加consistent参数则为普通取模哈希,节点变动时几乎全部重映射,而启用后基于ketama虚拟节点环机制,仅少量请求重定向,显著提升缓存命中率与会话稳定性。

要在 Nginx 中实现一致性哈希负载均衡,需启用 ngx_http_upstream_hash_module 模块(默认已编译进大多数官方发行版),并使用 hash 指令配合 consistent 参数。它不是靠 IP 固定分发,而是通过哈希环和虚拟节点机制,让后端增减时仅少量请求重定向,显著提升缓存命中率与会话稳定性。
配置一致性哈希的关键语法
普通 hash 默认是取模式分配,而一致性哈希必须显式声明 consistent:
-
hash $request_uri consistent;—— 基于请求路径做一致性哈希 -
hash $arg_user_id consistent;—— 基于 URL 参数(如 user_id)做哈希 -
hash $cookie_session_id consistent;—— 基于 Cookie 值做哈希,适合有状态服务
注意:consistent 必须写在分号前,且不能与 ip_hash 共存;同一 upstream 块中只允许一个 hash 指令。
为什么必须用 consistent 参数
不加 consistent 时,Nginx 使用的是简单取模哈希(类似 hash(key) % server_count)。一旦后端数量变化,几乎所有哈希结果都会变,导致大量请求打到新服务器,缓存失效、会话中断。
加上 consistent 后,Nginx 内部构建一个 32 位哈希环,每个真实 server 自动映射多个虚拟节点(默认 160 个),使哈希分布更均匀。节点增删时,只影响环上邻近的一小段区间,其余请求路由保持不变。
实际配置示例与注意事项
以下是一个基于用户 ID 参数的典型配置:
upstream api_cluster {
hash $arg_uid consistent;
server 10.0.1.10:8080;
server 10.0.1.11:8080;
server 10.0.1.12:8080;
}
- 若请求为
/user/profile?uid=12345,所有含该 uid 的请求始终落在同一台后端 - 某台机器下线时,原属它的请求只会迁移到哈希环上顺时针最近的存活节点,而非全部重分配
- 建议搭配
max_fails和fail_timeout使用健康检查,避免请求落到异常节点
和 ip_hash 的区别与选型建议
ip_hash 看似也是“固定分配”,但它基于客户端真实 IP 计算,存在明显局限:
- 公网用户经 NAT 或 CDN 后,大量请求可能映射到同一个出口 IP,造成单点过载
- IPv6 地址长度变化或代理透传不全时,哈希结果不稳定
- 后端扩缩容时整个哈希表重建,无法做到平滑迁移
一致性哈希更适合:需要长期绑定业务标识(如 user_id、tenant_id、device_id)的场景,尤其是微服务间调用、分布式缓存路由、消息队列分片等对数据局部性要求高的系统。


















