一致性哈希在upstream中应对节点缩容时的核心优势是仅少量请求重映射,因其基于哈希环与虚拟节点机制,缩容时只影响被删节点顺时针邻近区间;普通哈希则因hash(key)%n随n变化导致70%~90%请求重定向,引发缓存雪崩。

一致性哈希在 upstream 中应对节点缩容时的核心优势,是只让少量请求重映射,而不是全部打乱。它不靠“固定分配”,而是靠哈希环结构把请求和节点都落在同一个逻辑环上,缩掉一台机器,只影响它顺时针方向邻近的一段区间。
缩容时普通哈希会怎样
普通 hash(比如 hash $remote_addr;)本质是 hash(key) % N,N 是当前存活节点数。一旦缩容,N 变小,所有 key 的取模结果几乎全变:
- 原来 5 台机器时,key=123 →
123 % 5 = 3→ 落到 server3 - 缩成 4 台后,
123 % 4 = 3→ 还是 server3?碰巧而已;但 key=124 就从124%5=4变成124%4=0,直接跳到 server0 - 实测中,节点减少 1 台,平均约 70%~90% 的请求会重定向
这导致缓存集体失效、会话中断、连接重建风暴,尤其对 Redis 缓存层或带本地状态的 Java 应用非常致命。
一致性哈希怎么做到“少动”
它把每个后端节点(按 IP+端口)和请求 key 都映射到 0~2³²−1 的环上:
- 每个真实节点默认生成 160 个虚拟节点(权重为 w 的节点生成 w×160 个),均匀散列在环上
- 请求进来后,计算其 key 的 hash 值,顺时针找到第一个虚拟节点,对应的真实节点就是目标
缩掉一台物理机,只是移除它对应的那批虚拟节点。环上其他位置不变,只有原来落到这些被删虚拟节点上的请求,才会顺时针“滑”到下一个最近的虚拟节点——也就是邻近的一小部分请求迁移。
实测数据表明:启用一致性哈希后,单节点缩容引起的请求重映射比例通常低于 8%,远优于普通哈希。
真正起作用的前提条件
光写 consistent 不够,必须满足三点:
- 使用稳定 key:比如
$http_x_real_ip(比$remote_addr更准)、$uri(忽略参数干扰)、或清洗后的$arg_user - 后端节点配置带健康检查:
max_fails=2 fail_timeout=30s,否则宕机节点仍留在环上,请求会失败 - 推荐开启
keepalive 32;:避免重映射后频繁建连,放大抖动
权重怎么参与进来
一致性哈希本身不直接支持 weight,但可通过虚拟节点数量模拟:
- 权重为 3 的节点,等价于在环上部署 3 倍数量的虚拟节点
- Nginx 内部正是按
weight × 160自动计算虚拟节点数,所以server a:8000 weight=3天然比weight=1的节点承接更多请求区间
不复杂但容易忽略











