理解 Redis 的复制、Sentinel 和 Cluster 之后,我们已经能够回答两个基础问题:Primary 故障时如何接管,单个 Primary 达到容量或吞吐上限后如何分片。但在真实项目中,技术负责人面对的通常不是一道“Sentinel 还是 Cluster”的单选题。
例如,前两篇中的“光光平台”可能同时把 Redis 用于文章缓存、登录会话、邮件任务和接口限流:
article:8848 文章缓存
session:user:1001 登录会话
queue:email 邮件任务
rate-limit:user:1001 限流状态
这些数据都能写进 Redis,却有完全不同的故障含义。文章缓存丢失后可以从 PostgreSQL 重建;会话丢失会让用户重新登录;邮件任务被淘汰可能让通知永远无法发送;限流状态失效则可能让突发流量直接进入下游服务。如果只根据总内存选择一套 Redis,再让所有业务共用它,架构图可能很简单,故障半径却会越来越大。
这里的故障域,是指可能因同一个故障而同时失效的一组资源,例如同一进程、主机、可用区或地域。
生产架构选型需要同时回答五类问题:Redis 的基础设施生命周期由谁负责,应用如何访问 Redis,节点或可用区故障后谁来接管,整个地域不可用时如何恢复,以及不同业务是否应该共享资源和故障域。本文沿着这五类问题,讨论自建 Redis Open Source、代理、托管服务、多可用区和跨地域方案的特点与边界。
本文继续使用同一个虚构的“光光平台”作为案例,不代表本站当前的实际生产部署。Primary-Replica 复制与 Sentinel 的故障转移机制已经在《Redis 高可用原理:Primary-Replica 复制、Sentinel 与故障转移》中展开,哈希槽、客户端重定向和在线扩缩容则见《Redis Cluster 原理:哈希槽、请求路由与在线扩缩容》。本文不重复这些协议细节,而把注意力放在生产组织方式和选型过程上。
1. Redis 生产选型需要回答哪些问题
Redis 架构并不是节点数量越多越好。增加节点能够减少某些单点故障,也会增加连接、拓扑、复制、监控和故障排查的复杂度。一个可执行的选型过程,应先把业务目标翻译成可以验证的系统约束。
1.1 先区分容量、可用性与灾难恢复
三个经常被混用的目标实际上相互独立:
| 目标 | 要回答的问题 | 常见机制 |
|---|---|---|
| 横向扩展 | 单个 Primary 装不下数据或无法承担写入时怎么办 | Redis Cluster、托管分片 |
| 高可用 | 进程、主机或可用区故障后如何继续提供服务 | Replica、Sentinel、分片级故障转移 |
| 灾难恢复 | 整个地域不可用或数据被破坏后如何恢复 | 跨地域副本、备份、切流与回切流程 |
Redis Cluster 解决分片和分片级高可用,不等于已经具备地域级灾难恢复;保存一份异地备份也不等于故障发生时应用能够自动切换。架构评审时需要分别描述每个目标,而不是笼统地写“Redis 已做高可用”。
1.2 用 RPO 和 RTO 描述故障目标
恢复点目标(Recovery Point Objective,RPO)表示故障后最多允许丢失多少数据,恢复时间目标(Recovery Time Objective,RTO)表示从故障发生到服务恢复最多允许多长时间。
对于光光平台,文章缓存可以接受较大的 RPO,因为缓存能够重建;登录会话可能允许丢失少量数据,但应限制受影响用户数量;邮件任务如果承担可靠业务通知,则需要更小的 RPO,并且必须有任务幂等和补偿机制。这些要求会直接影响复制、持久化、备份和业务隔离方式。
Redis Open Source 默认使用异步复制。Primary 已确认但尚未到达 Replica 的写入,在故障转移中仍可能丢失。WAIT 可以降低丢写概率,却不会把 Redis 变成强一致系统。因此 RPO 不能只写“有一个 Replica”,还要结合复制延迟、持久化策略和应用事实源一起判断。
1.3 建立统一的比较维度
选择架构前,至少应收集以下信息:
- 数据集大小、增长速度、平均与峰值读写吞吐;
- 最大可接受延迟和尾延迟,以及请求是否能够重试;
- 单个 hot key、大 key、多 key 命令和 Lua 脚本的使用情况;
- 能否接受陈旧读、重复执行或短时间不可用;
- 节点、可用区和地域三个层级的 RPO、RTO;
- 应用客户端是否支持 Sentinel 或 Redis Cluster;
- 团队是否能够承担扩缩容、升级、备份和故障演练;
- 缓存、会话、队列和控制状态之间允许多大的故障耦合。
只有当这些维度明确后,“自建还是托管”“直连还是代理”才有可验证的答案。否则复杂架构只是把未知风险从应用侧移动到了基础设施侧。
2. 部署形态与运维责任如何选择
自建 Redis Open Source 的优势是访问路径直接、配置可控,也没有服务商控制面的抽象层。团队可以根据负载选择 Standalone、Primary-Replica、Primary-Replica + Sentinel 或 Redis Cluster,并决定节点布局、持久化和升级窗口。
这种控制力的另一面,是生产责任没有消失。Redis 进程能够启动,只证明实例可以运行,并不证明系统已经具备高可用、可恢复和可持续运维能力。
如果选择托管服务,节点生命周期的一部分会交给服务控制面,但数据模型和应用正确性责任仍然留在业务团队。本章先说明部署形态与自建责任,再比较托管服务能够接管什么。
2.1 非分片还是分片:先判断单个 Primary 能否承载
如果完整数据集能够放入单个 Primary,而且单 Primary 写吞吐足够,就应先在非分片形态内选择恢复责任。数据完全可重建、可以接受人工恢复时,Standalone 最简单;需要 Replica 提供数据冗余或分担读请求,但由人工或外部控制面完成切换时,可以使用 Primary-Replica;需要 Redis Open Source 自动判断故障、提升 Replica 并让客户端发现新 Primary 时,则使用 Primary-Replica + Sentinel,并验证客户端支持 Sentinel。
在跨故障域部署时,一个 Primary、两个 Replica 和三个 Sentinel 是常见拓扑。Replica 提供数据冗余,Sentinel 负责故障判断、选举和服务发现。它保留了普通多 key 操作和事务的使用方式,运维复杂度也低于分片集群。
如果单个 Primary 已经成为内存或写吞吐瓶颈,则需要分片。自建 Redis Open Source 通常使用 Redis Cluster:多个 Primary 分担 16384 个哈希槽,每个分片再配置 Replica;Redis Software、Redis Cloud 或其他托管产品也可能通过服务端分片和 Proxy 提供不同的接入协议。分片扩展的是总容量和分散后的写入能力,但使用 Redis Open Source Cluster 或兼容 API 时,应用必须使用能够维护 slot 到节点映射并处理重定向的 Cluster-aware client,还要面对 hash tag、CROSSSLOT、hot slot 和 resharding 等问题。
因此,生产环境并不因为“重要”就天然需要 Cluster。数据量很小、跨 key 操作较多的系统使用 Cluster,可能只得到更高的节点成本和更复杂的故障路径。应该先证明单个 Primary 的容量或写吞吐已经成为约束,再承担分片代价。
2.2 高可用首先取决于故障域布局
下面两种部署在进程数量上相同,故障能力却完全不同:
错误布局:
一台主机
├── Primary
├── Replica 1
├── Replica 2
├── Sentinel 1
├── Sentinel 2
└── Sentinel 3
合理布局:
故障域 A:Primary + Sentinel 1
故障域 B:Replica 1 + Sentinel 2
故障域 C:Replica 2 + Sentinel 3
第一种布局只能应对个别进程异常,主机故障会同时带走数据节点和 Sentinel 多数派。第二种布局才把相互依赖的角色分散到独立故障域。Cluster 也遵循相同原则:某个 Primary 与它唯一的 Replica 如果位于同一台主机或同一可用区,同一故障就可能让整个分片不可用。
故障域不仅是服务器。电源、交换机、机架、可用区、容器编排节点和共享存储都可能形成共同失效点。自建方案必须根据实际基础设施描述这些边界,不能仅凭逻辑拓扑判断冗余是否有效。
2.3 团队需要拥有完整运维闭环
自建 Redis 至少需要负责:
- 节点安装、配置、补丁和版本升级;
- CPU、内存、连接数、网络与磁盘容量规划;
- 复制延迟、Primary-Replica 连接中断、故障转移和 Cluster 状态监控;
- RDB、AOF、异地备份和恢复验证;
- Sentinel 切换、Cluster 扩缩容与 slot 再平衡;
- TLS、ACL、网络边界和凭据轮换;
- 节点、可用区和依赖服务的故障演练;
- 变更停止条件、回滚方案和事故响应流程。
尤其需要区分“有备份”和“能够恢复”。备份文件必须定期在隔离环境中验证能否加载,Cluster 则需要确认所有分片都有一致时间边界下的可用恢复材料。持久化、备份和恢复机制的详细边界见《Redis 持久化原理:RDB、AOF、数据恢复与生产实践》。
2.4 托管服务接管什么,又没有接管什么
托管 Redis 通常可以接管实例创建、硬件故障处理、自动故障转移、补丁、监控入口、备份和部分扩缩容流程。对于没有专职 Redis 运维团队的项目,这些能力能够把大量低频但高风险的操作交给服务控制面。
不过“托管”并不代表应用可以忽略 Redis 语义。团队仍然需要负责:
- 选择非分片或分片形态,确认客户端接入协议;
- 设计 key、TTL、hash tag、淘汰策略和容量水位;
- 处理超时、重试、重复执行和连接恢复;
- 区分可重建缓存与不可随意丢失的数据;
- 验证服务提供的 RPO、RTO、备份和跨地域能力是否满足业务;
- 通过故障演练确认应用真的能够重连和降级。
托管服务的命令支持、模块、扩缩容方式、网络接入和故障语义并不完全相同。选型时应以所选产品当前的官方文档和实际演练为准,而不是把某个厂商的行为概括成所有“云 Redis”的共同能力。本文不比较厂商价格或服务级别协议(Service Level Agreement,SLA),因为这些信息变化较快,也不能替代业务侧的恢复验证。
3. 请求路由由谁负责:Cluster-aware client 还是 Proxy
分片之后,应用必须找到保存目标 key 的节点。Redis Open Source Cluster 把这项责任交给客户端;Redis Software 等产品还可以通过代理隐藏分片拓扑。托管服务可能暴露 Cluster 访问地址(endpoint)、代理访问地址或其他形式,因此是否托管并不直接决定请求路径;本章只比较客户端直连与代理转发这两种路由责任。

3.1 Cluster-aware client 直接管理路由
图中左侧是 Redis Open Source Cluster 的典型请求路径:路由状态保存在应用使用的 Cluster client 中,请求不经过中心代理。
客户端启动时获取哈希槽与节点映射,随后根据 key 计算 slot,直接访问对应 Primary。拓扑变化时,客户端根据 MOVED 更新映射;传统 resharding 期间还要正确处理 ASK 和 ASKING。Redis 8.4+ 的 Atomic Slot Migration(ASM,原子哈希槽迁移)在快照和增量复制期间继续由源节点服务,但最终所有权交接时会短暂暂停源端写入;默认写暂停超时上限为 10 秒。团队仍需验证交接超时、重试和尾延迟,生产客户端也要兼容旧版本或传统迁槽工具。稳定状态下没有中心代理,少一次转发,也不存在单个代理承担全部数据流量的问题。
代价是复杂度进入了应用:客户端必须实现完整 Cluster 协议,连接池要同时维护多个节点,服务发现、TLS、拓扑刷新和连接风暴都需要验证。每种语言和客户端库的行为也可能不同。如果系统包含多种语言,团队需要分别验证它们在扩容、故障转移和地址变化时的表现。
3.2 Proxy 用稳定 endpoint 隐藏拓扑
图中右侧的代理式访问把请求路由从应用侧移动到基础设施侧。普通 Redis client 先连接稳定 endpoint,再由高可用 proxy 把请求转发到目标 shard。
应用只连接一个或一组稳定 endpoint,可以继续使用普通 Redis client,也不必直接感知节点迁移。对于语言栈较多、客户端能力不一致,或者希望集中管理 TLS、连接和路由的系统,这能明显降低接入复杂度。
但 Proxy 不是免费的抽象。请求多一次网络跳转,代理需要处理连接、带宽和每秒数据包;单个 Proxy 会形成新的性能瓶颈和故障点。因此生产代理层通常也需要多实例、负载均衡、健康检查和容量规划。
Proxy 隐藏拓扑,不代表所有产品都恢复成单实例命令语义。通用外置 Proxy 或后端启用 OSS Cluster API 时,跨 slot 多 key 约束通常仍然存在;Redis Software 专有分片模式可以跨 shards 执行 MGET、MSET、DEL 和 pipeline,但 MULTI/EXEC 事务、Lua 脚本及许多命令仍要求 keys 位于同一 slot。其中跨 shard 多 key 写能力不适用于 Active-Active:在 Active-Active 中,MGET 可以跨 slots 读取,而 MSET、DEL 和 UNLINK 仍然是 single-slot 操作。具体边界取决于后端分片协议、数据库形态和命令,不能从“有 Proxy”一项推导;hot key 和大 key 也不会被代理自动拆开。
Redis Software 内置 proxy,并由数据库 endpoint 接收请求、转发到具体 shard。官方文档同时提供单 proxy、绑定各 Primary 所在节点以及绑定所有节点等策略;多个活动 proxy 可以提高吞吐和故障接管能力,也会增加资源消耗,并可能因为 proxy 与 shard 分布在不同节点而增加延迟。这属于 Redis Software 的产品能力,不能当作 Redis Open Source Cluster 内置了通用代理。
4. 单区域多可用区为什么是常见生产基线
大多数业务首先需要应对的不是整个地域消失,而是 Redis 进程、宿主机或一个可用区故障。将 Primary 和 Replica 分布到同一区域内的不同可用区,通常能在延迟、成本和故障覆盖之间取得较好的平衡。
4.1 多可用区保护的是区域内部故障
以三可用区的 Sentinel 拓扑为例,Primary、Replica 和 Sentinel 需要分散到不同故障域;某个可用区故障后,剩余 Sentinel 形成多数派并提升健康 Replica。

图中假设 AZ-A 整体失联,因此旧 Primary 对所有应用入口都不可达。若只是部分网络分区,Sentinel 多数派可以提升 B,但仍能访问 A 的少数侧客户端可能继续写入旧 Primary;Sentinel 本身不会替应用完成写入隔离。min-replicas-to-write、min-replicas-max-lag 或外部 fencing 可以限制分叉窗口,但不能保证零丢失。
分片集群需要让每个 Primary 的 Replica 位于不同可用区,避免一个可用区故障同时带走某个分片的所有 Replica。对于自建 Redis Open Source Cluster,仅分散每组 Primary 和 Replica 还不够;Primary shards 自身也应跨可用区分散,使预期保护的故障域丢失后仍有可达 Primary 多数,并为每个故障 Primary 保留可提升的 Replica。故障发生后,Sentinel、Redis Cluster 或托管控制面提升可用 Replica;应用再通过服务发现、Cluster 拓扑或稳定 endpoint 恢复连接。
Redis Cloud 的高可用文档把复制分为无复制、同可用区复制和多可用区复制。多可用区形态会把 Primary 与 Replica 放到不同可用区,以便整个可用区不可用时仍能故障转移。按照当前产品边界,免费的 Redis Cloud Essentials 不提供复制;多可用区需要付费 Essentials 或 Pro,并要求所选地域至少有三个可用区。启用复制后,内存需求约为数据集的两倍。复制与 Zone 设置的变更规则需要按套餐区分:Essentials 创建为 Multi-zone 后不能改为 Single-zone 或关闭复制,但 No Replication 与 Single-zone 可以随时互换;Pro 的 Zone 设置在订阅创建后不能修改,但每个数据库仍可随时启用或关闭复制。只有需要改变这些不可变的 Zone 设置时,才需要新建订阅并迁移数据。这里描述的是 Redis Cloud 的具体能力;自建 Redis Open Source 不会自动替团队完成可用区放置、地址切换和恢复验证。
4.2 自动切换不代表请求无感
一次可用区故障通常仍然包含以下时间窗口:
故障发生
→ 探测超时
→ 多数派确认
→ Replica 晋升
→ 拓扑或 endpoint 更新
→ 客户端断开旧连接
→ 建立新连接并恢复请求
在这段时间内,应用可能收到连接重置、超时或只读节点错误。客户端必须设置有边界的退避与重试,业务操作还需要考虑幂等。对于 INCR、任务入队等操作,连接中断时客户端可能无法确定命令是否已经执行,盲目重试会造成重复结果。
多可用区也没有改变异步复制的基本事实。刚刚写入 Primary、尚未到达被提升 Replica 的数据仍可能丢失。因此它主要改善区域内 RTO 和故障覆盖,并不自动提供 RPO 为零的强一致保证。
4.3 多可用区不等于跨地域灾备
同一区域的多个可用区仍然可能共享区域级控制面、网络入口或上游依赖。区域整体不可用、错误数据同步到全部 Replica、凭据或配置同时失效时,区域内 Replica 可能无法提供恢复路径。
所以光光平台可以把多可用区作为文章缓存和 Session Redis 的常见生产基线,但如果业务明确要求地域级连续性,还需要独立设计跨地域数据复制、应用流量切换、回切和数据校验。它们不是多添加一个 Replica 就能自然获得的能力。
5. Active-Passive 如何完成跨地域灾备
Active-Passive 指正常情况下只有主地域承担写入,灾备地域保存异步副本、快照或预置集群,等待主地域不可用时接管。这种模式避免了多地域并发写冲突,是更容易理解和控制的跨地域方案。
Redis Open Source 可以跨网络建立复制链路,也可以使用备份在远端重建数据,但它不会因此自动获得一套完整的地域级 Active-Passive 控制面。旧主隔离、灾备提升、应用切流、数据校验与恢复回切,仍然需要外部基础设施和运维流程完成。
5.1 正常复制、故障切流与恢复回切
一条完整链路至少包含三个阶段:
- 正常阶段:用户请求进入主地域应用和 Redis,数据通过异步复制或备份进入灾备地域。
- 故障切换:停止或隔离旧写入口,检查灾备数据的新鲜度与完整性,解除目标端复制或只读关系,提升灾备数据库并开放写入,最后把全局流量切向灾备地域。
- 恢复回切:主地域恢复后,先重新建立一致的数据基线,再反向同步或重建主地域,最后灰度切回流量。

真正困难的通常不是“远端有一份数据”,而是如何防止两个地域同时接受互不兼容的写入,以及恢复后以哪一侧数据为准。
建立复制链路本身也可能删除目标端数据。Redis Software 将数据库定义为 Replica Of 目标时,会删除目标数据库的已有数据并用源端数据替换;Redis Cloud Pro 目标数据库启用 Active-Passive 时则会 flush 目标数据库。因此目标端应使用专用空库,或者先确认其中没有重要数据;如果必须复用已有数据库,应先完成备份并对清空操作进行明确确认。
Redis Software 把这项异地复制能力称为 Replica Of,目标数据库接收写请求前必须先解除 Replica Of 关系,否则后续全量同步可能覆盖灾备端的新写入。Redis Cloud 把对应形态称为 Active-Passive,其目标数据库需要位于 Redis Cloud Pro,源端可以来自 Redis Cloud Pro、Redis Cloud Essentials 或外部 Redis。如果源、目标都是 Redis Cloud 数据库,直接配置 Active-Passive 时需要位于同一 Redis Cloud 账号;跨账号迁移需要先联系 Redis 支持,不能把“外部 Redis”入口视为通用的跨账号绕过方式。
计划切换时,应先停止源端写入,等待目标端达到 Synced,再关闭 Active-Passive 并切换连接;非计划灾难中,源端可能已经不可达,无法继续等待追平,此时要先隔离旧写入口,检查目标端最后复制位置并接受对应 RPO,再关闭 Active-Passive、开放目标端写入。启用 Active-Passive 时直接写目标端,可能造成数据不一致和复制失败。
只要 Replica Of 或 Active-Passive 仍然启用,目标数据库就不会独立执行 key 过期和淘汰,而是依赖源端传播的数据变化。灾备端不能把本地 TTL 或淘汰策略当作容量保护,应为完整同步数据及复制波动预留内存,并在切换演练中验证解除复制关系后的 TTL、淘汰和容量表现。
Redis Open Source 则需要显式提升 Replica,并由外部流程完成旧写入口隔离。无论使用哪种产品,切换前都要有明确的写入隔离(fencing)措施;回切前则要确认原主地域不会带着旧状态重新加入并覆盖新数据。
5.2 复制延迟决定实际 RPO
跨地域网络的往返延迟、带宽和抖动通常高于区域内复制。异步复制能够避免每次写入都等待远端,却意味着灾备地域总可能落后。主地域突然丢失时,实际 RPO 由灾备端已经接收和持久化到什么位置决定,而不是由“跨地域复制已开启”这句话决定。
对于文章缓存,这个窗口通常可以接受,因为数据库仍是事实源;对于 Session,它可能表现为部分用户重新登录;对于邮件任务,则可能造成任务遗漏或重复,需要业务记录、幂等键和补偿扫描共同处理。越依赖 Redis 保存不可重建状态,越需要把复制延迟和恢复校验纳入监控。
5.3 灾备方案必须包含应用流量
数据库已经在灾备地域可写,应用也不一定能够立即恢复。DNS 缓存、负载均衡健康检查、网络访问控制、TLS 证书、密钥、配置中心和下游数据库都可能阻塞切流。
因此 Active-Passive 的 RTO 是以下过程之和,而不只是 Redis Replica 晋升时间:
故障确认
+ 数据新鲜度判断
+ 数据库提升
+ 应用和网络切流
+ 客户端重连
+ 业务验证
灾备操作手册(runbook)还必须覆盖恢复回切(failback)。只有定期演练“切过去”和“切回来”,并验证数据差异、连接恢复和业务降级,才能把异地副本转化为真实的灾难恢复能力。
6. Active-Active 如何允许多个地域同时写
Active-Passive 在远离主地域的用户请求上通常仍需要跨地域访问,或者只允许读取本地 Replica。如果多个地域都必须以本地延迟读写同一数据集,就进入了 Active-Active 的范围。
6.1 多 Primary 写入为什么需要冲突语义
假设上海和法兰克福同时修改同一个计数器:
上海: INCR article:8848:view-count
法兰克福:INCR article:8848:view-count
网络分区期间,两边都不能立即看到对方的操作。恢复连接后,如果系统只保留最后到达的值,其中一次增长就可能消失。字符串覆盖、集合增删、计数器累加和列表操作需要的合并规则也不相同,不能用同一种“最后写入获胜”规则准确表达所有意图。
冲突自由复制数据类型(Conflict-free Replicated Data Type,CRDT)把合并规则编码进数据类型,使多个副本在分别接受更新后,能够在收到相同操作集合时收敛到一致结果。它解决的是并发更新如何确定性合并,不是让跨地域操作瞬间同步。

6.2 最终一致性的业务边界
Redis Active-Active 使用强最终一致性模型:网络正常并且更新完成传播后,各地域最终收敛;传播完成前,各地读到的值可以不同。即使冲突能够自动解决,应用仍要理解短时间不一致和跨 key 业务约束。
这类架构适合:
- 全球用户需要在就近地域更新偏好、购物车或非关键状态;
- 计数、集合等操作可以按照对应 CRDT 语义合并;
- 业务能够接受跨地域短时间读取不同值;
- 地域间网络中断时仍希望每个地域继续写入。
它不应在没有额外正确性设计的情况下承担余额、账本、全局唯一库存扣减、全局锁或要求严格顺序的任务队列。CRDT 可以解决定义范围内的冲突合并,却不会自动满足跨多个 key 的事务不变量。
Active-Active 还会改变容量和淘汰边界。每个参与地域不仅要容纳数据集,还要为 CRDT 元数据和跨地域 Active-Active backlog 预留内存;区域内数据库复制还会引入 Replica 和数据库复制 backlog。Redis Software 官方文档指出,这些开销可能让数据库所需内存增加到两倍或更多。Redis Cloud Active-Active 本身要求启用区域内数据库复制:Primary 与 Replica 先使内存需求达到约两倍,Active-Active 复制再叠加一层,内存上限影响最高可能达到原始数据集的四倍。这些数字是产品容量规划边界,不是可以套用到所有部署的固定公式,选型时仍应按具体数据类型、写入速率和产品配置重新估算。
6.3 Redis Software、Redis Cloud 与 Open Source 的能力边界
Redis 官方提供的 CRDT Active-Active 是 Redis Software 和 Redis Cloud 的产品能力:Redis Software 可以自主管理企业级集群;Redis Cloud Active-Active 则需要使用支持该能力的 Redis Cloud Pro 订阅。Redis Software 把同一数据库部署到至少两个参与集群;Redis Cloud 在多个地域建立可读写的数据库副本。两种形态都会在地域间进行多 Primary 复制和冲突解决。
Redis Open Source 的 Sentinel 和 Redis Cluster 不提供同等的跨地域 CRDT Active-Active:Sentinel 维护单个逻辑 Primary,Cluster 虽然有多个 Primary,但每个 hash slot 在稳定状态下仍由一个 Primary 负责写入。不能把“Cluster 有多个 Primary”理解为“同一份 key 可以在多个地域同时写”。
即使使用 Redis Software 或 Redis Cloud Active-Active,应用连接的跨地域 failover 和 failback 也不是自动消失的。Redis 官方文档明确要求应用通过全局流量管理、代理、支持故障转移的客户端或应用逻辑,把请求从不可用地域切到远端数据库。因此还要独立设计 endpoint 健康检查、流量切换和恢复后的回切策略。
连接切到远端实例也不代表 RPO 为零。Active-Active 复制和区域内 Primary-Replica 复制都是异步的;远端 endpoint 可能尚未收到本地已经确认的写入。若原地域只是暂时故障,这些写入可能在恢复后继续收敛;若本地持久化文件同时丢失,它们也可能永久丢失。因此 Active-Active 仍需要持久化、备份、复制延迟监控和业务补偿。
Active-Active 的淘汰策略也会比普通数据库更早介入:当任一实例达到内存上限的 80% 时,Redis Software 和 Redis Cloud 就会开始执行配置的淘汰策略,为跨地域传播预留空间。Redis Software 官方规划文档还特别提醒,如果数据库使用 noeviction,同时又没有能够过期的 key,OOM 可能让跨地域复制持续失败并造成实例失同步。在 Redis Software 中,运行 Redis 8.4 及以上版本的 Active-Active 数据库可以通过复制 OOM 缓冲区为内部复制保留内存,但它不能替代容量水位、backlog 和复制状态监控。
7. 为什么缓存、会话、队列和控制状态需要隔离
选择完节点拓扑后,还需要决定不同业务是否共用一套 Redis。命名空间隔离能够避免 key 重名,却不能隔离 CPU、内存、淘汰、持久化、延迟尖峰和节点故障。生产事故中,真正危险的往往不是 key 名冲突,而是一个业务耗尽资源后拖垮所有 Redis 用途。
7.1 四类负载有不同的故障语义
| 用途 | 数据能否淘汰 | 常见持久化要求 | 主要故障影响 |
|---|---|---|---|
| Cache | 通常可以 | 较低,数据可从事实源重建 | 命中率下降、数据库压力上升 |
| Session | 通常不应随意淘汰 | 取决于能否接受用户重新登录 | 用户掉线、登录状态回退 |
| Queue / Stream | 不应淘汰未处理数据 | 通常较高,并需要任务补偿 | 任务丢失、重复或积压 |
| Control | 不应意外淘汰 | 取决于限流、幂等和锁的正确性要求 | 重复执行、并发冲突、保护失效 |
缓存 Redis 通常允许 allkeys-lru 或 allkeys-lfu 淘汰低价值数据,并通过 TTL 控制生命周期。Session、Queue 和控制状态则更常选择 noeviction,在容量不足时显式失败和告警,而不是静默删除仍有业务意义的 key。
Redis 官方淘汰策略文档也指出:如果一个实例同时保存可淘汰缓存和需要保留的 key,即使可以使用只淘汰带过期时间 key 的策略,条件允许时仍应考虑拆为两个实例。原因不仅是策略更清晰,也包括容量和故障影响能够独立管理。
7.2 Queue 和控制状态还需要业务正确性
把 Queue 单独部署并启用 AOF,不代表任务处理正好一次。消费者可能在任务已经完成、确认消息尚未成功时崩溃,故障切换也可能造成重复读取或状态回退。任务执行必须具备幂等键、重试上限、死信或补偿扫描,并为积压量和最老任务年龄设置告警。
分布式锁和幂等控制也不能只依赖一个 Redis key 承担最终正确性。异步复制切换后,锁或幂等键可能丢失;锁持有者还可能在长时间暂停后继续写入。余额、订单唯一性等约束应由事务数据库唯一索引、状态机或单调递增的隔离令牌(fencing token)等机制兜底;使用隔离令牌时,资源端必须拒绝比当前版本更旧的令牌。Redis 更适合作为快速协调层,而不是不可推翻的事实来源。
限流的要求则取决于失败策略:面向普通页面的限流可以在 Redis 不可用时暂时放行(fail-open),保护昂贵下游接口的限流可能需要在失败时拒绝请求(fail-closed)。两者即使使用相同算法,也不一定适合共享故障策略。
7.3 从命名隔离逐步升级到故障域隔离
常见隔离方式可以分为五级:
| 隔离方式 | 能隔离什么 | 不能隔离什么 |
|---|---|---|
| Key prefix | 命名空间 | CPU、内存、淘汰、持久化、故障 |
| ACL / User | 访问权限和命令范围 | 资源争用与实例故障 |
| 逻辑数据库 | Key 视图 | 进程、内存、淘汰和故障;Cluster 只支持 DB 0 |
| 独立实例 | 内存上限、淘汰、持久化和发布节奏 | 共享宿主机或可用区故障 |
| 独立高可用集群 | 资源、配置和发布节奏;可以独立规划故障域 | 若仍共享宿主机、可用区、网络或控制面,基础设施故障仍会共同影响 |
拆分不应机械地采用“一项功能一个 Redis”。更合理的标准是数据价值、资源曲线和故障策略是否一致。如果两个缓存具有相似 TTL、可以共同降级并且负载平稳,可以共享实例;如果邮件任务不能被淘汰,而文章缓存会持续挤占内存,就应该至少拆成独立实例。业务隔离的目标是限制故障半径,而不是让架构图拥有更多方框。
对于光光平台,可以将文章缓存、登录会话、邮件任务和控制状态按各自的数据价值、资源曲线和故障策略逐步拆分,并为它们独立规划容量与故障域:

项目早期可以先进行逻辑分类和监控,达到容量、淘汰或故障语义边界时再物理拆分。独立 Redis 若仍共用宿主机、可用区或控制面,只形成了工作负载边界,不等于已经隔离基础设施故障;节点放置仍需按第 2.2 节的故障域原则设计。这样既避免过早建设四套小集群,也保留了清晰的演进路径。
8. 如何把业务需求转换成最终拓扑
Redis 生产架构没有脱离业务约束的标准答案。一个可复用的决策顺序,是先决定是否分片,再决定区域内高可用、跨地域恢复和业务隔离,最后分别确定由 Cluster-aware client 还是 Proxy 承担请求路由,以及由团队自建还是托管服务承担基础设施生命周期。
8.1 一棵从单节点到跨地域的决策树
完整数据集和峰值写吞吐能否由一个 Primary 承载,是决策树的第一个分叉。但在把“不能承载”翻译为分片前,应先确认瓶颈不是单个 hot key、big key 或无法拆分的单请求:Cluster 只能把不同 keys 分散到多个 shards,不能自动拆开一个 key 或针对它的集中访问。只有负载能够按独立 keys 分散时,分片才能扩大总容量和分散写入。此后再分别判断区域内故障转移、分片路由、地域级恢复、工作负载隔离和运维责任。
接入能力也必须按实际协议验证。非分片自动切换需要支持 Sentinel 服务发现的 client,或者由托管控制面或 Proxy 提供真正随 Primary 变化的稳定 HA endpoint;固定节点地址不具备这一能力。分片时,普通 Redis client 只有连接到真正隐藏 MOVED、ASK 和拓扑变化的高可用 Proxy 或 HA endpoint 才能工作;如果 endpoint 暴露 Redis Cluster 协议,仍然需要 Cluster-aware client,不能把所有托管 endpoint 泛化为代理式接入。

决策树中的每一步都应由数据支持。例如,“需要分片”应有单机内存、峰值吞吐或增长预测证据;“需要 Active-Active”应有多地域同时写和本地延迟目标,而不只是希望架构更先进。
8.2 光光平台的一个渐进式选择
对于本文虚构的光光平台,可以得到如下方案:
- 文章缓存:优先使用单区域多可用区的非分片高可用 Redis;只有容量或分散写入达到单 Primary 边界时才升级为分片形态,再根据客户端能力和运维责任选择 Redis Open Source Cluster 或托管分片。跨地域时,各地域可以分别从 PostgreSQL 或内容源构建本地缓存,通常没有必要同步全部缓存写入。
- 登录会话:使用独立高可用 Redis,根据用户能否接受重新登录决定 AOF、跨地域副本和 RPO。多地域同时修改同一 Session 前,需要先定义冲突语义。
- 邮件任务:使用独立
noeviction实例,配置复制与持久化,并由数据库任务记录、消费者幂等和补偿扫描保证最终完成;如果可靠性要求超出 Redis 队列边界,应评估专门的消息系统。 - 限流与幂等:可以共享控制类 Redis,但要按接口选择 fail-open 或 fail-closed;订单唯一性等最终约束仍由 PostgreSQL 保证。
- 业务事实源:文章、用户、订单和任务最终状态继续保存在 PostgreSQL,Redis 负责缓存、短期状态和加速,不承担无法重建的唯一事实。
如果团队没有成熟的 Redis 值班、扩缩容和恢复能力,托管多可用区 Redis 通常比自建复杂拓扑更容易形成完整闭环;如果对访问路径、部署环境和配置有强控制要求,并且团队能够承担故障演练,自建 Redis Open Source 也可以是合理选择。二者的区别不是“专业”与“不专业”,而是运维责任由谁持有。
8.3 本文的八个结论
综合来看,Redis 架构选型可以归纳为以下结论:
- Sentinel 解决非分片 Primary 的自动接管,Redis Cluster 解决分片和分片级高可用,两者不是同一规模下的替代品。
- 高可用、横向扩展和灾难恢复是三个独立目标,需要分别描述故障域、RPO 和 RTO。
- Cluster-aware client 用应用复杂度换取直接访问路径;proxy 用基础设施复杂度换取稳定 endpoint。
- 托管服务可以接管大量基础设施操作,但不会替应用设计 key、重试、幂等和降级。
- 单区域多可用区是常见生产基线,跨地域 Active-Passive 还需要切流和回切流程。
- CRDT Active-Active 属于 Redis Software 和 Redis Cloud 能力,提供多地域写与最终收敛,不等于强一致;选型时还要接受额外的复制、CRDT 元数据与 backlog 容量开销,以及更早介入的淘汰阈值。它不消除异步复制的 RPO 边界。
- 缓存、会话、队列和控制状态应根据淘汰、持久化与故障语义决定是否拆分,而不是只靠 key prefix 共用一切。
- 对不能接受已确认写入丢失的最终业务状态,应保留具备相应事务和持久性保证的事实源。
参考资料
- Redis replication
- Redis Sentinel
- Redis Cluster specification
- Scale with Redis Cluster
- Redis Open Source:CLUSTER MIGRATION
- Redis Cloud:High availability and replication
- Redis Software:Configure proxy policy
- Multi-key operations across Redis configurations
- Redis Software:Replica Of geo-distributed Redis
- Redis Software:Create a database with Replica Of
- Redis Cloud:Migrate data with Active-Passive
- Redis Cloud:Data eviction
- Redis Software:Active-Active geo-distributed Redis
- Redis Software:Considerations for planning Active-Active databases
- Redis Cloud:Active-Active Redis
- Redis Cloud:Database memory limits and sizing
- Application failover with Active-Active databases
- Redis key eviction