一致性哈希通过哈希环映射提升缓存命中率,增删节点仅影响局部请求;需选用稳定键(如$request_uri)、正确编译启用consistent_hash模块,并结合虚拟节点、健康检查与细粒度缓存设计。

一致性哈希能显著提升多台代理网关的缓存命中率,核心在于让相同请求长期落在同一台后端节点上,避免节点增减时全量缓存失效。它不靠取模硬分配,而是把节点和请求都映射到一个 0~2³²−1 的哈希环上,请求顺时针找到最近节点——这样增删一台机器,只影响环上相邻的一小段请求,其余缓存仍可命中。
选对哈希键是命中的前提
键决定“谁和谁总打到同一台”,必须稳定、有业务意义:
- $request_uri:适合静态资源或固定路径接口(如 /static/logo.png 或 /api/user/profile),URI 不变则始终路由一致,CDN 和本地缓存复用率高
- $remote_addr:适用于需按客户端 IP 保持会话的场景(如登录态透传),但注意 NAT 环境下多个用户共用一个出口 IP,容易造成负载倾斜
- $arg_product_id 或 $args:适合带关键参数的查询(如 ?product_id=789),能绑定业务维度,前提是参数本身稳定、不含时间戳或随机 token
- 避免用 $time_iso8601、$request_id 这类每次必变的变量,否则哈希结果完全随机,一致性就失效了
正确启用 consistent_hash 模块
该模块非 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,后者是官方 hash 模块语法,二者不兼容)
- 示例配置:
upstream cache_backend {
consistent_hash $request_uri;
server 10.0.1.10:8080 weight=3;
server 10.0.1.11:8080 weight=2;
server 10.0.1.12:8080 weight=1;
}
用虚拟节点和健康检查防倾斜
单纯一致性哈希无法自动应对节点性能差异或单点过热,需叠加机制:
- 模块默认支持虚拟节点(每个物理 server 映射多个环上位置),权重越高,分配的虚拟槽位越多,自然分担更多请求
- 配合主动健康检查(如 check interval=3 rise=2 fall=3 timeout=1),及时剔除异常节点,防止哈希环局部失衡导致请求堆积
- 若发现某 URI 成为热点(如 /product/10001 请求暴增),可在 location 块中预处理 key,例如:set $ch_key "$host$request_uri"; 再 consistent_hash $ch_key;,避免单一路径压垮单节点
命中率不是单靠算法,还要看缓存设计
一致性哈希解决的是“路由稳”,但最终命中还依赖缓存内容本身是否合理:
- 缓存粒度尽量细:缓存单个商品详情,比缓存整个商品列表更易命中、更新成本更低
- 避免缓存含动态字段的数据:比如响应里带当前时间、随机 nonce,会导致每次生成不同响应体,即使 URI 相同也无法复用
- 监控真实命中率:Nginx 自身不直接暴露缓存命中指标,可通过 upstream 状态码(如 200 from cache vs 200 from upstream)、日志分析,或在后端加 X-Cache 头辅助判断

















