nginx/上游负载均衡

让相同 key 稳定命中上游

nginx 的 consistent hash 将上游展开为有序哈希点,再用二分查找定位请求 key 的落点。

release-1.26.3通信与流量核验 2026-10-08
相关概念

工程问题#

缓存代理希望相同 key 尽量送到同一上游,并在节点变动时减少 key 的重新分配范围。

实际实现#

初始化构造并排序哈希点数组;请求计算 CRC32,查找首个大于等于请求哈希的点,再选择可用上游。

处理流程#

  1. 按上游与权重建立哈希点
  2. 排序并去掉重复点
  3. 二分定位请求 key 的位置
  4. 检查候选上游并按规则重试

源码片段#

固定版本 · 原文摘录
src/http/modules/ngx_http_upstream_hash_module.crelease-1.26.3 · L438–L459
查看原文件
438    /* find first point >= hash */439440    point = &points->point[0];441442    i = 0;443    j = points->number;444445    while (i < j) {446        k = (i + j) / 2;447448        if (hash > point[k].hash) {449            i = k + 1;450451        } else if (hash < point[k].hash) {452            j = k;453454        } else {455            return k;456        }457    }458459    return i;
ngx_http_upstream_find_chash_point

在已排序、去重的哈希点数组中二分查找第一个不小于请求哈希的下标。返回值可能等于点数;调用方随后取模实现环回,并另行检查上游可用性。O(log P) 描述的是点定位,不是含重试的整个请求流程。

连续函数主体;参数声明及外层花括号不在片段中。环由有序数组表达,不是环形链表。

收益与取舍#

工程分析

带来的收益

  • 有序数组具备紧凑存储与局部性
  • 点查找为对数级,映射相对稳定

付出的代价

  • 工程分析:虚拟点数量带来额外空间
  • 热点 key 和上游故障仍可能造成负载不均

可比较的选择

简单取模哈希计算更简单,但上游数量改变时通常影响更多 key。

版本与适用范围#

对应 hash 指令的 consistent 模式;这里的哈希环由数组表达,并非环形链表。

参考来源#

源码、官方文档与原始论文
01
nginx · ngx_http_upstream_init_chash / ngx_http_upstream_find_chash_point

src/http/modules/ngx_http_upstream_hash_module.c · ngx_http_upstream_init_chash / ngx_http_upstream_find_chash_point

源码release-1.26.3

相关实现与比较#

2 个相关案例
8 个匹配案例