一致性哈希:分布式缓存里的数据分配算法

从普通取模的问题讲到哈希环、虚拟节点、节点扩缩容和热点 key,理解一致性哈希的工程边界。

已发布文章计算机基础入门5 分钟阅读发布于 2026年9月1日更新于 2026年9月15日
文章目录
  1. 它从哪里来
  2. 普通取模的问题
  3. 一致性哈希环
  4. 虚拟节点
  5. 简化实现
  6. 工程注意点
  7. 我的分析
  8. 面试题
知识目录数据结构与算法:从基础到工程实践73 / 77
LOCAL NOTE高亮并记笔记
0 / 1000 · 只保存在这台设备
READER NOTES一致性哈希:分布式缓存里的数据分配算法》的本机笔记

我对“一致性哈希:分布式缓存里的数据分配算法”的理解经历过一个从会背到会用的过程。其中最明显的一点是:我最初做缓存分片只想到对节点数取模,节点一扩缩容,大量键同时迁移的问题很快就暴露出来。后来每次看到结论,我都会追问它省掉了哪一步、又付出了什么代价,这也是这篇文章的主线。

一致性哈希常用于分布式缓存、分布式存储和负载分配。它解决的问题是:当节点增加或减少时,如何尽量少迁移数据。

它从哪里来

一致性哈希由 David Karger 等人在 1997 年提出,用于分布式缓存等节点会变化的系统。普通取模在节点数量变化后会让大量键重新映射;哈希环和虚拟节点则把迁移限制在局部范围。

普通取模的问题

最简单的分片方式是:

nodeIndex = hash(key) % nodeCount;

如果有 3 个节点,这个方法看起来很自然。但一旦节点数从 3 变成 4,大量 key 的取模结果都会变化,缓存会大面积失效。

一致性哈希环

一致性哈希环

图:key 顺时针找到第一个节点;节点变化时只影响局部区间

一致性哈希把哈希空间看成一个环:

  1. 把服务器节点 hash 到环上。
  2. 把数据 key 也 hash 到环上。
  3. key 顺时针找到的第一个节点,就是负责它的节点。

当新增一个节点时,只会接管它逆时针方向到前一个节点之间的数据;当删除一个节点时,也只需要把它负责的数据交给下一个节点。

虚拟节点

如果真实节点数量少,节点在环上分布可能不均匀,导致某些机器压力很大。虚拟节点可以缓解这个问题。

做法是:给每台真实机器创建多个虚拟节点。

node-A#1, node-A#2, node-A#3
node-B#1, node-B#2, node-B#3
node-C#1, node-C#2, node-C#3

每个虚拟节点都 hash 到环上,最终再映射回真实节点。

简化实现

class ConsistentHash {
    private final TreeMap<Integer, String> ring = new TreeMap<>();
    private final int replicas;

    ConsistentHash(int replicas) {
        this.replicas = replicas;
    }

    void addNode(String node) {
        for (int i = 0; i < replicas; i++) {
            ring.put(hash(node + "#" + i), node);
        }
    }

    String getNode(String key) {
        if (ring.isEmpty()) return null;
        int h = hash(key);
        Map.Entry<Integer, String> entry = ring.ceilingEntry(h);
        if (entry == null) {
            entry = ring.firstEntry();
        }
        return entry.getValue();
    }
}

TreeMap 用来找到大于等于当前 hash 的第一个节点。如果找不到,就回到环的起点。

工程注意点

一致性哈希不是分布式系统的全部答案。真实落地还要考虑:

  • 节点权重:大机器应该承载更多虚拟节点。
  • 故障探测:节点挂了要及时摘除。
  • 数据迁移:新增节点后是否主动预热。
  • 热点 key:单个 key 太热时,一致性哈希也救不了。
  • 副本策略:缓存或存储通常需要多个副本提高可靠性。

我的分析

一致性哈希的核心价值是“降低变化成本”。它不是让数据永远不迁移,而是让节点变化时只迁移局部数据。

我会把它放在数据结构与算法专题里,是因为它很好地连接了哈希、环形空间、有序查找和工程分布式问题。学完它以后,再看缓存集群、网关负载、分布式存储,会更容易理解。

面试题

  1. 普通 hash(key) % n 在扩容时有什么问题?
  2. 一致性哈希为什么能减少数据迁移?
  3. 虚拟节点解决什么问题?
  4. 一致性哈希能否解决热点 key?
  5. 一致性哈希和 Redis Cluster 槽位思想有什么相似和不同?
JARVIS · 当前文章

有哪里没看懂?可以只问这篇。

Jarvis 会限定在《一致性哈希:分布式缓存里的数据分配算法》及其公开关联内容中检索,并把引用定位回原文章节。

JARVIS / ARTICLE针对《一致性哈希:分布式缓存里的数据分配算法》提问
当前范围一致性哈希:分布式缓存里的数据分配算法不会悄悄扩大到全站
0 / 1000

准备好了。当前只会围绕一致性哈希:分布式缓存里的数据分配算法回答。

READER SIGNAL

这篇内容对你有帮助吗?

不需要登录。你的反馈会直接进入作者待处理列表。