type
Post
status
Published
date
Dec 4, 2025
slug
redis3
summary
tags
技术探索
category
icon
password
很多人一提到 Redis,第一反应就是:快。
Redis 快,很大一部分原因是它把数据放在内存里。
但这也带来一个很现实的问题:
内存是有限的。
假设一台 Redis 机器可用内存只有 64GB,但业务要缓存 300GB 热点数据,怎么办?
有人可能会说:那就多加几个从节点。
但这样其实解决不了问题。
因为主从复制只是把同一份数据复制多份。
Master 有 64GB 数据,Replica 也复制这 64GB 数据。
它解决的是:
Master 挂了以后,服务还能不能继续用。
但它解决不了:
数据太多,一台 Redis 放不下。
真正想突破单机 Redis 的内存上限,就不能再让每台 Redis 保存完整数据,而是要把数据拆开,让不同 Redis 节点保存不同的数据。
这就是 Redis Cluster,也就是 Redis 集群模式要解决的核心问题。
一、单机 Redis 为什么不够用?
最开始,我们使用 Redis 的方式通常很简单。
业务服务直接连接一个 Redis 实例。
业务服务把热点数据放进 Redis,查询时优先访问 Redis,查不到再回源数据库。
因为 Redis 基于内存,读写性能很高,所以它非常适合做缓存、计数器、分布式锁、排行榜等高频访问场景。
但单机 Redis 有两个明显问题。
第一个问题是:容量有限。
Redis 数据主要放在内存里,而一台机器的内存不可能无限大。
假设一台 Redis 机器可用内存是 64GB,而业务需要缓存 300GB 热点数据,那么单机 Redis 再快,也放不下这些数据。
第二个问题是:单点故障。
如果这个 Redis 实例挂了,所有依赖它的业务请求都会受到影响。
所以,单机 Redis 最大的问题不是性能不够,而是:
容量有上限,可用性也有风险。
二、主从复制解决了什么,又没解决什么?
为了解决单点故障问题,我们很自然会想到 Redis 主从复制。
架构大概是这样:
Master 负责处理写请求,Replica 复制 Master 的数据。
这样做的好处是:
如果 Master 挂了,可以从 Replica 里选出一个新的 Master,继续对外提供服务。
所以,主从复制解决的是:
Redis 节点挂了以后,服务还能不能继续用的问题。
也就是高可用问题。
但主从复制并不能解决容量问题。
因为 Replica 保存的是 Master 的全量数据。
如果 Master 里有 64GB 数据,那么 Replica 也会复制这 64GB 数据。
这只是把同一份数据复制了多份,并没有把数据拆开。
主从复制解决的是高可用,不是容量扩展。
所以如果业务数据已经超过单机内存上限,单纯增加 Replica 没有用。
三、Redis Cluster 到底是什么?
既然单机 Redis 放不下,主从复制也不能扩展容量,那该怎么办?
答案是:分片。
所谓分片,就是把一份大数据拆成多份,分别放到不同 Redis 节点上。
这就是 Redis Cluster 的核心思想。
Redis Cluster 是 Redis 官方提供的分布式集群方案。
它是把数据拆分成多个分片,分散存储到多个 Master 节点上。
每个 Master 节点只负责一部分数据。
为了保证高可用,每个 Master 通常还会配置一个或多个 Replica。Replica 复制对应 Master 的数据。一旦 Master 宕机,Replica 可以被选举成新的 Master,继续负责原来的数据分片。
所以 Redis Cluster 可以简单理解成:
Redis Cluster = 数据分片 + 主从复制 + 故障转移。
它同时解决两个问题:
第一,单机 Redis 内存有限,数据放不下。
第二,单个 Redis 节点挂了,服务不能不可用。
四、Redis Cluster 的架构是什么样的?
从整体架构上看,Redis Cluster 通常由多个 Master 和多个 Replica 组成。
这张图里有几个关键角色。
第一,客户端。
Redis Cluster 原生模式下,没有一个统一的中心代理节点。
客户端通常需要具备 Cluster 感知能力,也就是能够缓存 slot 到节点的映射关系,并根据重定向响应更新本地路由。
当然,业务也可以额外引入代理层,但这不是 Redis Cluster 的核心机制。
第二,多个 Master 节点。
多个 Master 共同承担数据存储。
每个 Master 只负责一部分数据,而不是保存全量数据。
第三,多个 Replica 节点。
每个 Replica 复制对应 Master 的数据,用来做故障转移。
第四,哈希槽。
Redis Cluster 并不是直接把 key 分给某个 Redis 节点,而是先把 key 映射到哈希槽,再由哈希槽映射到具体节点。
第五,节点间通信。
Redis Cluster 节点之间会互相通信,用来感知节点状态、槽位归属变化和故障信息。
所以 Redis Cluster 的核心架构可以概括成一句话:
多主分片 + 主从高可用 + 哈希槽路由。
五、有限内存 Redis,为什么能支撑大规模缓存?
严格来说,Redis 不能支持真正意义上的“无限数据”。
因为 Redis 仍然依赖机器内存,集群里所有节点的总内存也是有限的。
但 Redis Cluster 可以通过不断增加 Master 节点,把数据分散到更多机器上,让整体容量随着节点数量增长。
这就是所谓的水平扩展。
单机 Redis 的容量上限,取决于一台机器的可用内存。
Redis Cluster 的逻辑容量上限,主要取决于整个集群中所有 Master 节点的可用内存总和。
举个例子。
如果单台 Redis 可用内存约 64GB,业务要缓存 300GB 热点数据,那么理论上至少需要 5 个 Master:
300GB / 5 = 60GB
也就是:
Master 1 约 60GB
Master 2 约 60GB
Master 3 约 60GB
Master 4 约 60GB
Master 5 约 60GB
但真实生产环境不能把 Redis 内存打满。
你还要考虑:
- 系统内存预留;
- 数据倾斜;
- 复制缓冲区;
- AOF rewrite 开销;
- big key 风险;
- 突发写入;
- 内存碎片;
- 后续扩容空间。
所以真实环境下,300GB 热点数据可能不会只规划 5 个 Master,而是可能规划 6 到 8 个 Master,甚至更多。
此外,如果每个 Master 都配置 Replica(Master和Replica部署在不同机器上),那么 Replica 也需要额外占用内存。
所以 Redis Cluster 支撑大规模缓存的本质是:
用多台 Redis 机器的内存,组成一个更大的逻辑存储空间。
它是用多台 Redis 一起承载数据。
这也是 Redis Cluster 和主从复制最大的区别。
主从复制是复制同一份数据。
Redis Cluster 是拆分不同的数据。
六、数据到底怎么分到不同 Redis 节点?
既然 Redis Cluster 要把数据分散到多个 Master 节点上,就必须解决一个问题:
一个 key 到底应该放到哪个节点?
最容易想到的方案是:
对 key 做 hash,然后对 Redis 节点数量取模。
比如:
假设现在有 3 个 Redis 节点。
某个 key 经过 CRC16 计算后,hash 值是 10。
那么:
10 % 3 = 1
这个 key 就放到 Redis 1 上。
这个方案看起来很简单。
但它有一个致命问题:
节点数量一变,大量 key 的映射结果都会变化。
比如原来有 3 个节点:
后来业务增长,需要扩容,节点数量从 3 个变成 4 个。
公式就变成:
同一个 key,原来对 3 取模,可能落到 Redis 1。
现在对 4 取模,可能落到 Redis 2。
这就会导致一个很严重的问题:
数据明明还在旧节点上,但客户端按照新规则去新节点查,结果查不到。
如果大量 key 的路由关系都发生变化,就会带来两个后果。
第一,大量缓存失效,请求回源数据库,可能把数据库打崩。
第二,数据迁移成本非常高,需要重新计算大量 key 的归属关系。
所以,直接对节点数量取模,不适合 Redis Cluster 这种需要动态扩容、缩容的集群架构。
七、Redis Cluster 为什么要引入哈希槽?
为了解决这个问题,Redis Cluster 引入了一个中间层:
哈希槽,Hash Slot。
Redis Cluster 固定有 16384 个哈希槽,编号从 0 到 16383。
每个 key 会先计算出自己属于哪个槽:
然后 Redis Cluster 再根据槽位归属,找到对应的 Redis 节点。
也就是说,Redis Cluster 的路由关系不是:
key -> node
而是:
key -> slot -> node
画成图就是:
这个中间层非常关键。
因为 key 到 slot 的映射是固定的。
无论集群里有 3 个节点,还是 4 个节点,计算公式始终是:
变化的是:
哪些 slot 归哪个 Redis 节点负责。
比如现在有 3 个 Master 节点,可以把 16384 个槽大致分成三段:
如果某个 key 算出来的 slot 是 3000,它就属于 Master 1。
如果某个 key 算出来的 slot 是 9000,它就属于 Master 2。
如果某个 key 算出来的 slot 是 15000,它就属于 Master 3。
所以,哈希槽解决的本质问题是:
如何稳定地把 key 分配到不同 Redis 节点上。
八、哈希槽为什么适合扩容?
哈希槽真正厉害的地方,是让扩容和缩容变得更可控。
假设一开始有 3 个 Master 节点:
后来业务数据越来越多,我们想新增一个 Master 4。
如果使用“key 对节点数量取模”的方案,节点数量从 3 变成 4,大量 key 的路由结果都会变化。
但使用哈希槽以后,槽的总数不会变。
依然是 16384 个槽。
扩容时,只需要从原来的节点上迁移一部分槽到新节点。
这时候,key 到 slot 的映射没有变。
变的只是 slot 到 node 的映射。
这里要注意一个细节:
逻辑上迁移的是 slot,但真正搬迁的数据,还是这个 slot 下面的 key。
slot 是管理和路由单位。
key 才是真正的数据单位。
所以“迁移 slot”不是把一个空槽号挪过去,而是要把这个槽对应的一批 key 逐步迁移到新节点上。
这就是哈希槽适合扩容的核心原因:
扩容时迁移的是一部分槽,以及这些槽里的 key,而不是让所有 key 重新计算节点归属。
所以哈希槽的价值,不只是把 key 分散出去,更重要的是让集群扩容和缩容变得可控。
九、客户端怎么访问 Redis Cluster?
理解了哈希槽以后,客户端访问 Redis Cluster 的流程就很好理解了。
假设客户端要执行:
它会先计算这个 key 对应的 slot:
然后根据 slot 找到负责这个槽的 Redis 节点。
成熟的 Redis Cluster 客户端通常会缓存一份 slot 到节点的映射关系。
这样客户端不需要每次都问集群:
这个 slot 归谁?
它可以自己直接算出 key 的 slot,然后访问对应节点。
但还有一种情况:
客户端本地缓存的 slot 映射过期了。
比如集群刚刚做过扩容,某些槽已经迁移到了新节点,但客户端还按照旧映射访问老节点。
这时候 Redis 会返回重定向响应。
Redis Cluster 里常见的重定向主要有两种:
MOVED 和 ASK。
十、MOVED 和 ASK 有什么区别?
先看 MOVED。
MOVED 通常表示:
这个 slot 已经稳定归属于另一个节点了。
比如某个 key 对应的 slot 已经归 Master B 负责了,但客户端还请求 Master A。
客户端收到 MOVED 后,一般会更新本地 slot 路由缓存。
也就是说,以后这个 slot 的请求,就应该直接发给 Master B。
再看 ASK。
ASK 通常出现在 slot 迁移过程中。
比如某个 slot 正在从 Master A 迁移到 Master B。
这个过程中,有些 key 可能还在 Master A,有些 key 可能已经迁移到了 Master B。
这时候如果客户端访问 Master A,而目标 key 已经被迁移走了,Master A 可能会返回 ASK,告诉客户端:
这次请求先去 Master B 试一下。
MOVED 和 ASK 的区别可以这样记:
所以客户端访问 Redis Cluster 的核心链路是:
计算 key 的 slot → 找到负责 slot 的节点 → 发送请求 → 根据 MOVED/ASK 处理重定向。
十一、Redis Cluster 如何保证高可用?
前面讲的是分片,也就是怎么解决单机 Redis 放不下的问题。
但 Redis Cluster 还要解决另一个问题:
某个 Master 节点挂了怎么办?
所以 Redis Cluster 通常会给每个 Master 配置 Replica,Master和Replica部署在不同机器上。
每个 Master 负责一部分槽。
每个 Replica 复制对应 Master 的数据。
如果某个 Master 挂了,集群可以从它的 Replica 中选出一个新的 Master。
新的 Master 会继续负责原来那部分槽。
所以 Redis Cluster 的高可用依赖两件事:
第一,Master 和 Replica 之间的数据复制。
第二,Master 故障后,Replica 可以自动升级为新 Master,并接管原来的 slot。
但这里一定要注意:
Redis Cluster 的高可用不等于强一致。
Redis 的主从复制通常是异步复制。
也就是说,Master 写入成功以后,这条数据不一定已经同步到了 Replica。
如果 Master 写入成功后,还没来得及把数据同步给 Replica 就宕机了,那么 Replica 被提升为新 Master 后,就可能缺少这部分最近写入的数据。
所以 Redis Cluster 提高的是可用性,不是强一致性。
它可以让服务尽快恢复,但不能保证极端故障下数据一定不丢。
如果业务对一致性要求非常高,就不能把 Redis Cluster 当成强一致的核心数据源。
十二、Redis Cluster 不是银弹
Redis Cluster 解决了单机容量瓶颈,也提供了高可用能力。
但它不是没有代价。
数据一旦被拆分到多个 Master 上,跨节点操作就会变复杂。
最典型的问题是:多 key 操作受限。
比如:
如果
user:1 和 user:2 落在不同 slot 上,它们就可能由不同 Master 负责。这时候 Redis Cluster 很难在一个节点上完成这个多 key 操作。
事务和 Lua 脚本也有类似限制。
因为 Redis Cluster 没有提供跨多个 Master 的分布式事务能力。
所以多个 key 如果要参与同一个多 key 命令、事务或 Lua 脚本,通常需要落到同一个 slot。
那怎么让相关 key 落到同一个 slot 呢?
可以使用 hash tag。
比如:
Redis Cluster 会优先对
{1001} 这部分内容计算 slot。这样这几个 key 就会落到同一个 slot 里,也就会被分配到同一个 Master 上。
这适合一些强相关的数据,比如同一个用户的资料、购物车、订单缓存等。
但 hash tag 也不能滥用。
如果大量 key 都使用同一个 hash tag,就可能导致某个 slot 特别热,进而让某个 Master 压力过大。
所以 Redis Cluster 的限制可以总结成几句话:
它能解决分片和扩容问题,但会增加客户端路由复杂度。它能做高可用,但不等于强一致。它支持多 key 操作,但多个 key 通常要在同一个 slot。它适合大规模热点数据缓存,但不适合无限承载所有冷数据。
如果数据规模特别大,还要结合淘汰策略、冷热分层、数据库、搜索引擎、对象存储等系统一起设计。
Redis Cluster 不是用来替代所有存储系统的。
它更适合承载:
大规模、高并发、可接受一定一致性风险的热点数据。
十三、Redis Cluster 和主从、哨兵有什么区别?
为了避免混淆,可以简单对比一下。
主从复制的重点是:
一个 Master,多个 Replica,Replica 复制 Master 的全量数据。
它解决数据副本和读扩展问题,但不能解决容量扩展问题。
哨兵模式的重点是:
监控 Master 状态,Master 挂了以后自动选举新的 Master。
它解决自动故障转移问题,但本质上仍然是单主数据模型,数据没有被拆分到多个 Master。
Redis Cluster 的重点是:
多个 Master 分片存储数据,每个 Master 再配 Replica 做高可用。
它既解决容量扩展,也解决高可用。
简单总结:
主从复制:解决数据复制和读扩展
哨兵模式:解决主节点故障自动切换
Cluster:解决数据分片 + 高可用 + 水平扩展
一句话区分:
主从和哨兵主要解决“节点挂了怎么办”,Redis Cluster 进一步解决“单机放不下怎么办”。
十四、所以有限内存 Redis 是怎么支撑大规模数据的?
现在回到最开始的问题:
单机 Redis 内存有限,Redis Cluster 是怎么支撑大规模数据的?
Redis Cluster 不是让一台 Redis 变成无限内存。
它的做法是:
第一,把数据拆分成 16384 个哈希槽。
第二,把这些哈希槽分配给不同的 Master 节点。
第三,每个 Master 只保存自己负责的那部分数据。
第四,如果数据继续增长,就增加新的 Master,并迁移一部分槽和槽里的 key 过去。
第五,每个 Master 配置 Replica,保证节点故障后可以尽快恢复服务。
所以 Redis Cluster 支撑大规模数据的本质是:
通过分片,把数据分散到多台 Redis 机器上;通过扩容,让整体容量随着 Master 节点数量增长。
这就是水平扩展。
但要注意,它不是没有上限。
Redis Cluster 的容量上限仍然受限于:
- 集群中所有 Master 的总内存;
- Replica 带来的额外资源成本;
- key 分布是否均匀;
- 网络带宽;
- 节点数量;
- 槽迁移成本;
- 运维复杂度;
- 业务能接受的延迟和一致性要求。
Redis Cluster 通过水平扩展突破单机内存限制,从而支撑更大规模的热点数据。
十五、总结
Redis Cluster 解决的核心问题是让 Redis 突破单机容量和单点故障的限制。
单机 Redis 很快,但内存有限。
主从复制可以提高可用性,但不能扩展存储容量,因为 Replica 复制的是 Master 的全量数据。
Redis Cluster 的思路是把数据拆开,让多个 Master 节点分别负责不同的数据分片。
为了让数据分片更稳定,Redis Cluster 引入了 16384 个哈希槽。
每个 key 先通过 CRC16 计算出所属槽,再根据槽位归属找到对应 Redis 节点。
也就是:
key -> slot -> node
扩容时,只需要迁移一部分槽和这些槽里的 key 到新节点,而不是让所有 key 重新分布。
同时,每个 Master 可以配置 Replica。一旦 Master 挂了,Replica 可以升级为新的 Master,继续负责原来的槽。
不过 Redis Cluster 不是银弹。
它不是强一致,异步复制下仍然可能丢失少量最近写入的数据。
它也不适合无限承载所有数据,尤其是冷数据和强一致核心数据。
它更适合承载:
大规模、高并发、可水平扩展、可接受一定一致性风险的热点数据。
所以 Redis Cluster 可以概括成一句话:
Redis Cluster = 哈希槽分片 + 多主存储 + 主从复制 + 故障转移 + 客户端路由。
有限内存的 Redis 之所以能支撑大规模数据,是因为它通过集群分片,把数据分散到了更多机器上,用水平扩展突破了单机内存上限。
Redis Cluster架构图:
分享
