
本文将带你从最初的哈希分片算法讲起,逐步理解一致性哈希的设计思想, 再到 Redis Cluster 的 16384 槽位机制,完整串联分布式缓存分片的演进历程。
当单机 Redis 无法承载全部数据或并发压力时,我们自然会想到 —— 分片。 最直接的方式是采用哈希取模:
slot = hash(key) % N
假设有 4 个 Redis 节点:
hash(key1) % 4 = 0 → Redis0
hash(key2) % 4 = 1 → Redis1
这种方式实现简单、性能高,数据分布也较为均匀。 但问题是:扩容或缩容时,灾难性的数据迁移几乎不可避免。
如果原来有 4 台节点,后来要扩到 5 台:
slot = hash(key) % 5
此时所有 key 的取模结果都会变化,意味着:
在高并发环境下,这几乎是不能容忍的。
一致性哈希的核心思想是:
不再通过简单的取模分配,而是把所有的 key 和节点放到一个「哈希环」上。
假设哈希函数的取值范围是 0 ~ 2³²-1, 把这个范围首尾相连形成一个环。 每个节点通过哈希函数计算出一个位置:
0 ----- A(100) ----- B(200) ----- C(300) ----- 2^32-1
每个 key 也通过相同哈希函数计算哈希值, 然后沿环顺时针找到第一个节点,该节点负责存储这个 key。
例如:
hash(key)=150 → 存在节点B上 hash(key)=250 → 存在节点C上
当新节点 D 加入后:
这就是“一致性”的来源:节点变化只影响局部。
但是,一致性哈希并非完美。 由于节点哈希值分布随机,有可能出现某个节点负责的环区间过大,负载不均。
每个物理节点在哈希环上映射多个虚拟节点:
A#1, A#2, A#3, B#1, B#2, C#1 ...
每个虚拟节点独立计算哈希值,参与分布, key 落在某个虚拟节点后,再归属到它对应的物理节点。
这样一来:
Redis 官方在 3.0 推出的 Cluster 模式,可以看作是一致性哈希思想的工程化实现, 但它采用了更可控、更细粒度的“槽位机制(Slot)”。
Cluster 将整个 key 空间划分为 16384 个槽位(Slot)。 每个节点负责其中一部分槽位:
Node A: 0 - 5460 Node B: 5461 - 10922 Node C: 10923 - 16383
每个 key 的槽位通过 CRC16 计算:
slot = CRC16(key) % 16384
当需要迁移时,只需搬动部分槽位即可。 例如:
这种机制结合了“一致性哈希的平滑性”和“工程化的可控性”。
Redis 之所以设计成 slot 机制,而不是直接用哈希环,有三点原因:
设计目标 | 一致性哈希的局限 | Redis Cluster 的改进 |
|---|---|---|
数据均衡 | 需要虚拟节点调优 | 固定 16384 槽位可控分配 |
元数据同步 | 客户端本地维护环结构 | 节点间使用 Gossip 协议 |
迁移粒度 | 难以精准迁移 | 以 slot 为粒度精确迁移 |
Cluster 的设计更“工程化”, 它的槽位机制让迁移、扩容、Failover 都可控、可监控、可回溯。
阶段 | 代表算法 | 特点 | 缺点 |
|---|---|---|---|
哈希分片 | hash(key)%N | 实现简单 | 节点变动全量迁移 |
一致性哈希 | 哈希环 + 虚拟节点 | 局部迁移、平滑扩容 | 配置复杂、难监控 |
Redis Cluster | 16384 槽位机制 | 可控迁移、高可用、Gossip 管理 | 实现复杂、节点通信成本高 |
从最初的哈希分片,到一致性哈希,再到 Redis Cluster, 我们看到的是分布式系统设计从“算法优雅”到“工程落地”的全过程。
一致性哈希解决的是数学上的稳定性问题, Redis Cluster 解决的是生产环境下的可控性与可维护性问题。
理解这三者的演进,你就掌握了分布式缓存系统的核心设计哲学。