一致性哈希通过哈希环实现请求稳定路由,避免节点变动导致缓存大规模失效;键选$request_uri适配静态资源缓存,$remote_addr适用于会话保持,需规避动态变量;须编译添加第三方模块并正确配置consistent_hash指令,配合健康检查、权重与虚拟节点优化负载均衡。

用 consistent_hash 配置 upstream,核心是让相同客户端或相同请求特征长期落在同一台后端节点上,减少节点变动时的缓存失效。它不依赖节点总数取模,而是把节点和请求都映射到一个哈希环上,增删节点只影响邻近小部分请求。
选择合适的一致性哈希键
键的选择直接决定缓存复用效果和负载分布是否合理:
- $remote_addr:适合 IP 相对稳定、需按用户会话保持路由的场景(如登录态服务),但注意 NAT 环境下可能大量用户共用一个 IP,造成倾斜
- $request_uri:适合静态资源或 API 接口级缓存(如 /api/v1/user/123),URI 相同则总打到同一节点,提升 CDN 或本地响应缓存命中率
- $args 或 $arg_xxx:适用于带关键参数的查询(如 ?product_id=456),能精准绑定业务维度,但需确保参数稳定、无随机值(如时间戳、token)
- 避免用 $time_iso8601、$request_id 这类每次请求都变的变量,否则失去一致性意义
启用 consistent_hash 模块并正确配置 upstream
该模块非 Nginx 官方内置,需编译时显式添加:
- 从 GitHub 获取模块:
https://github.com/replay/ngx_http_consistent_hash - 重新编译 Nginx,添加参数:
--add-module=/path/to/ngx_http_consistent_hash - 在
upstream块中使用指令(注意语法无空格):
consistent_hash $request_uri;
不是consistent_hash$request_uri或hash $request_uri consistent—— 后者是官方ngx_http_upstream_hash_module的写法,二者不兼容 - 示例配置:
upstream cache_backend {
consistent_hash $request_uri;
server 10.0.1.10:8080 weight=2;
server 10.0.1.11:8080 weight=2;
server 10.0.1.12:8080 weight=1;
}
配合健康检查与虚拟节点缓解倾斜
一致性哈希本身不能自动解决节点权重差异或单点过热问题,需叠加机制:
- 启用主动健康检查(如
check interval=3 rise=2 fall=3 timeout=1),及时剔除异常节点,防止哈希环局部失衡 - 模块内部已默认支持虚拟节点(每个物理 server 映射多个环上位置),但可通过调整权重放大效果:高配机器设更高
weight,模块会自动分配更多虚拟槽位 - 若发现某 URI 路由集中(如热点商品页),可加一层预处理,例如提取路径前缀做 hash:
set $ch_key "$scheme://$host$request_uri";再consistent_hash $ch_key;,分散粒度
验证与调优要点
上线后不能只看是否转发,要确认“一致性”真正生效:
- 用固定 URI(如
curl -I http://gw.example.com/static/logo.png)反复请求,检查X-Upstream-Addr或 access_log 中 upstream_addr 是否始终一致 - 模拟下线一台 server,观察其余节点日志:只有约 1/N 的请求(N 为原节点数)发生重路由,而非全部刷新
- 监控各节点的缓存命中率(如 Redis 的
keyspace_hits / (keyspace_hits + keyspace_misses)),一致性生效后,单节点命中率应稳定在 85%+,大幅高于普通轮询或 IP Hash


















