Rendezvous Hashing 和一致性哈希有什么区别?
简化版
Rendezvous Hashing 又叫最高随机权重哈希:对每个 key,计算它和每个节点的哈希得分,选择得分最高的节点。它不需要哈希环,节点增删时只有受影响 key 迁移,常用于分布式分片和副本选择。
详细版
一致性哈希通常把节点和 key 放到哈希环上,key 顺时针找到节点。Rendezvous Hashing 不建环,而是对每个 key 给所有节点打分:
- score = hash(key, node)。
- 选择 score 最大的节点。
- 要多个副本时,选得分最高的前 N 个节点。
- 节点新增或删除时,只影响原本选择该节点或新节点胜出的 key。
它概念简单,副本选择自然,但节点很多时每次选择要计算多个得分,可能需要优化。
完整版教学
一、为什么需要稳定分片
分布式系统要把 key 分配到节点。简单取模 hash(key) % nodeCount 在节点数量变化时会导致大量 key 迁移。
3 个节点变 4 个节点
hash % 3 变 hash % 4
大部分 key 结果都会变
稳定分片算法的目标是:节点变化时,只迁移必要的一小部分 key。Rendezvous Hashing 和一致性哈希都服务这个目标。
二、Rendezvous Hashing 怎么选节点
对每个 key,计算它和所有节点的组合哈希得分:
scoreA = hash(key, nodeA)
scoreB = hash(key, nodeB)
scoreC = hash(key, nodeC)
选择分数最高的节点
例如 key=user:7:
nodeA: 0.21
nodeB: 0.83
nodeC: 0.45
选择 nodeB。这个选择是确定性的:同样的 key 和节点列表,在所有客户端上都能算出同样结果。
三、节点新增时为什么迁移少
新增 nodeD 后,原有 key 会多算一个分数。只有当 nodeD 的分数超过原最高分时,这个 key 才迁移到 nodeD。
原最高 nodeB = 0.83
新增 nodeD = 0.30 -> 不迁移
新增 nodeD = 0.91 -> 迁移到 D
平均来看,新节点会接走约 1/(N+1) 的 key。原节点之间的归属不会互相打乱,这就是稳定性的来源。
四、删除节点时会发生什么
如果删除 nodeB,只有原本分配给 nodeB 的 key 需要重新选择。它们会落到剩余节点中分数第二高的节点。原本不属于 nodeB 的 key 不受影响。
这点非常适合故障转移。要选多个副本时,直接取分数最高的前 3 个节点即可:
排序后:B, D, A, C
主副本:B
副本:D, A
节点 B 故障后,D 自然成为第一候选。
五、和一致性哈希对比
| 维度 | 一致性哈希 | Rendezvous Hashing |
|---|---|---|
| 核心结构 | 哈希环 | key-node 打分 |
| 虚拟节点 | 常用于均衡 | 可用权重得分实现 |
| 多副本 | 环上继续找后继 | 取 Top N 得分 |
| 选择成本 | 查环 O(log N) 常见 | 朴素 O(N) |
Rendezvous 的概念非常直接,但节点很多时每个 key 扫所有节点会贵。工程上可以通过分层、缓存、候选集缩小等方式优化。
六、权重如何处理
如果节点容量不同,可以使用加权 Rendezvous Hashing,让大节点更容易得到高分。具体公式实现有多种,但思想是让权重参与得分比较。
记忆钩子:一致性哈希是在环上找“下一个”,Rendezvous 是给所有节点打分找“最高分”。
七、常见误区与追问
- 误区:Rendezvous Hashing 需要哈希环。 它不需要环,而是计算 key 与每个节点的得分。
- 误区:节点新增会打乱所有 key。 只有新节点得分超过原最高分的 key 会迁移。
- 误区:它只能选一个节点。 取分数最高的前 N 个即可自然得到副本列表。
- 追问:它的主要成本是什么? 朴素实现每次要对所有节点算分,节点多时成本较高。
- 追问:和一致性哈希谁更好? 看场景;Rendezvous 简洁、多副本自然,一致性哈希查找可更容易优化。
八、加强记忆
Rendezvous Hashing 可以想成每个 key 和每个节点“约会打分”,谁分高就去谁那里。节点增删只影响赢家变化的 key,多副本就是取前几名。它和一致性哈希目标相似,但模型不是环,而是排名。