这几年但凡涉及到分布式系统设计,无论是面试、架构评审还是技术方案选型,Redis 的架构设计都是绕不开的必考题。尤其是系统架构设计师这个层面,单纯会读写 Redis 已经不够了,真正的分水岭在于:你能不能讲清楚为什么单机 Redis 扛不住的时候,该用主从、哨兵还是 Cluster?CAP 和 BASE 到底怎么指导你做取舍?这篇内容是我梳理 Redis 分布式架构设计的第一篇,聚焦在理论模型和高可用/集群的核心设计逻辑上,把架构师视角的思考链路完整走一遍。
无论你是正在准备系统架构设计师考试,还是需要在项目中独立完成缓存架构设计,又或者只是想把 Redis 的原理彻底吃透,这篇文章都会给你一条清晰的主线。我会把 CAP 理论、BASE 思想、主从复制、哨兵机制、Cluster 集群这些概念串成一个整体,而不是孤立地背概念。读完你会明白:架构设计里的每一个选择,背后都是理论在支撑。
1. 内容整体设计与思路拆解:从单机到分布式的必然之路
1.1 为什么架构师必须先理解 CAP 而不是先学命令
很多同学的 Redis 学习路径是从命令开始的,SET、GET、HSET玩得很溜,但一旦遇到“如何设计一个支撑百万 QPS 的缓存层”这样的问题就卡壳了。原因很简单:命令是术,架构是道。单机 Redis 再快,也逃不过内存上限、单点故障、带宽瓶颈这三座大山。当你开始考虑“多台 Redis 一起干活”的时候,CAP 理论就不可避免地浮出水面。
CAP 理论是分布式系统设计的基石,它告诉我们:在网络分区(Partition)客观存在的前提下,一致性和可用性只能二选一。这不是数学证明,而是分布式系统里一个被反复验证的物理现实。作为架构师,你必须先接受这个约束,才能理解 Redis 后续所有架构演进背后的逻辑。
我见过不少同学在面试时把 CAP 背得滚瓜烂熟,但一问到“Redis 集群为什么放弃强一致性?”就哑火了。原因就是他们只背了结论,没有理解推导过程。这篇内容我会带着你把这个推导过程完整走一遍,让你不仅能背,还能真正用起来。
1.2 高可用与集群:两条不同的技术路线
Redis 的高可用架构和集群架构,很多人容易混为一谈。实际上这是两个维度的东西:高可用解决的是“坏了怎么办”,集群解决的是“不够用怎么办”。
高可用架构以主从复制(Replication)+ 哨兵(Sentinel)为核心。它的目标是在主节点宕机时,系统能自动把从节点提升为主节点,对外几乎无感知地继续提供服务。这里的核心矛盾是:主从之间数据同步需要时间,切换期间必然存在短暂的数据不一致窗口。
集群架构以 Redis Cluster 为核心。它的目标是把数据分散到多个节点上,让总容量和总吞吐可以水平扩展。这里的核心矛盾是:数据分布要靠槽位(Slot)机制来管理,节点增减时要处理数据迁移,客户端要处理重定向。
在实际项目中,二者往往需要组合使用:Cluster 解决容量和吞吐,每个分片内部再用主从来保证可用性。理解了这条主线,你就能把 Redis 架构设计的所有知识点串起来,而不是散落一地的碎片。
2. CAP 理论深度拆解:Redis 在分布式一致性坐标中的位置
2.1 CAP 的三要素到底在说什么
CAP 理论由 Eric Brewer 在 2000 年提出,核心论断是:一个分布式系统不可能同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance)这三个需求,最多只能同时满足其中两个。
这里最容易让初学者误解的就是“一致性”。CAP 中的一致性指的是线性一致性,也叫强一致性:任何时刻,所有节点看到的数据都是同一个版本,读操作必须返回最新写入的结果。举个例子,如果你往 A 节点写入了x = 1,那么在写操作返回成功之后,任何客户端从任何节点读x,都必须是1,而不是旧值0。
可用性指的是:每个请求都能在合理时间内得到非错误的响应,但不保证响应里的数据是最新的。注意这里强调的是“非错误响应”,而不是“正确响应”。也就是说,系统可以返回旧数据,但不能拒绝服务。
分区容错性指的是:系统在网络分区(部分节点之间通信中断)的情况下,仍然能继续运行。网络分区不是“可能不会发生”的小概率事件,在真实分布式环境里,交换机故障、网线松动、网络拥塞都会导致分区,所以分区容错性是必选项。
注意:很多教材说“CAP 三者取其二”,这是不准确的。更严谨的说法是:由于网络分区在现代分布式系统中无法完全避免,所以 P 是必选项,你真正能选择的是在发生分区时,优先保证 C 还是优先保证 A。这也对应了 CP 系统和 AP 系统两大流派。
2.2 为什么 Redis 主从架构是 AP 而不是 CP
有了上面的基础,我们再来看 Redis 主从架构。Redis 的主从复制是异步的,这是一个关键的设计决策。
主节点收到写请求后,先写自己的内存,然后返回客户端OK,同时把写命令异步地传给从节点。这个“异步”就意味着:从节点上的数据总是落后于主节点的。如果你刚写完主节点,立刻去读从节点,很可能读到的是旧数据。在某些极端场景下,如果主节点在同步完成前宕机了,这部分最新写入的数据就彻底丢失了。
从 CAP 的视角看,当主从之间发生网络分区时,Redis 选择的是:主节点继续提供服务,写操作正常返回,从节点暂时收不到同步数据。这就是典型的 AP 选择——牺牲一致性,换取可用性。
这个取舍正确吗?在绝大部分业务场景下是合理的。缓存系统本身允许数据有一定的滞后性,比如用户修改了个人资料头像,头像在几秒内还没有在全网所有节点上生效,用户完全感知不到。但如果为了强一致性,每次写操作都要等从节点确认后才返回,写性能会下降一个数量级,这是所有高并发业务都无法接受的。
2.3 CP 与 AP 场景的边界:什么时候 Redis 不适合
理解了 Redis 是 AP 系统,你就应该清楚地知道它的能力边界。如果你的业务对数据一致性有强要求,Redis 不应该作为唯一的数据源。典型的不适合场景包括:
- 库存扣减:超卖问题不容忍任何不一致,应该用数据库事务或分布式锁配合强一致存储。
- 账户余额:金额错误会直接导致资损,异步复制带来的数据丢失不可接受。
- 订单状态流转:状态跳变会导致后续流程错乱,需要强一致保证。
在这些场景中,Redis 只适合做前置缓存或热点数据的加速层,主数据源必须是具备强一致能力的数据库。架构师要时刻记住:Redis 是缓存,不是一个完整的数据库。这里没有对错,只有合不合适。
3. BASE 理论:Redis 高可用架构设计的指导思想
3.1 BASE 是对 CAP 的进一步落地
BASE 理论是 CAP 的延伸,由 eBay 的架构师提出,核心思想是:即使做不到强一致性,也可以采用适合业务的方式让系统达到最终一致。BASE 是三个词的首字母缩写:
- Basically Available(基本可用):系统在出现故障时,允许损失部分可用性,比如响应时间变长、部分功能降级,但核心功能仍然可用。
- Soft State(软状态):允许系统在不同节点之间存在数据不一致的中间状态,这个状态不需要实时同步。
- Eventually Consistent(最终一致):虽然数据在各个节点之间不是实时一致的,但经过一段时间的同步和补偿,最终数据会达到一致状态。
BASE 理论本质上是一种妥协哲学:在互联网海量用户、高并发的场景下,强一致性往往意味着低可用性,这是用户无法接受的。所以我们应该退而求其次,用最终一致性来换取系统的整体可用性和性能。
3.2 Redis 主从同步如何实现最终一致
Redis 的主从复制机制就是 BASE 理论最标准的实践案例。
当主节点产生新的写操作时,它会把命令追加到复制缓冲区,然后异步地推送给从节点。从节点接收并执行这些命令后,自己的数据就逐步跟上主节点。这个过程就是“软状态”的典型表现:主从之间的数据在一段时间内是不一致的,但通过持续的复制,最终会达成一致。
这里有两个关键实现细节值得关注:
第一个是复制偏移量。主节点和从节点各自维护一个偏移量,表示已经处理到的复制流位置。主节点知道自己发送到哪里,从节点知道自己接收并执行到哪里。当从节点与主节点断开重连后,通过偏移量可以判断该从哪个位置补发数据。
第二个是增量复制与全量复制的切换。如果从节点断开时间很短,偏移量还在主节点的复制积压缓冲区(repl_backlog)内,可以走增量复制,效率很高。如果断开时间太长,积压缓冲区的数据已经被覆盖,就只能做全量同步,这就是 RDB 快照传输加重放,代价较大。
注意:很多运维同学遇到过“从节点同步延迟越来越大”的问题,本质上是主节点的写压力太大,复制流生成速度大于从节点应用速度。这时的解决方案不是盲目调参,而是要考虑给从节点扩容、降低主节点写入压力,或者使用更快的磁盘和网络。
3.3 最终一致性的代价:延迟窗口和数据丢失风险
选择 BASE 和最终一致性不是没有代价的。作为架构师,你必须清醒地认识到两个风险:
第一个风险是一致性窗口。从主节点写入到从节点同步完成,中间有一段时间窗口。在这段时间内,如果客户端从从节点读取数据,可能读到旧值。业务上要评估这个窗口是否可以接受。比如用户修改昵称后,在小范围时间内读到的还是旧昵称,这个体验是可以接受的;但如果是交易场景,任何窗口都不可接受。
第二个风险是数据丢失。如果主节点在把新数据同步给从节点之前宕机了,这段时间内写入的数据就丢了。Redis 本身也提供了wait命令和WAIT参数来让写操作等待从节点确认,但这会显著增加写延迟,并且会降低可用性,一般在关键场景才使用。
我见过一个典型的踩坑案例:某公司用 Redis 做主存储,在高峰期主节点宕机,哨兵提升从节点后,发现丢了最近几秒的订单数据,导致一批订单状态异常。后来排查确认,正是因为异步复制带来的数据丢失,而业务方没有做兜底。架构设计中,任何对一致性的放弃都要有配套的补偿机制。
4. 高可用架构核心:主从复制与哨兵机制全解析
4.1 主从复制的完整链路与核心参数
Redis 主从复制的高层流程可以用简单的话概括:从节点向主节点发起同步请求,主节点生成 RDB 快照发给从节点,从节点加载快照,然后主节点持续推送增量命令。但细节里有很多值得注意的参数和边界条件。
第一步是连接建立。从节点通过REPLICAOF命令(老版本是SLAVEOF)指定主节点的 IP 和端口,然后向主节点发送PSYNC命令请求同步。
第二步是全量同步。主节点收到PSYNC后,如果决定做全量复制,会执行BGSAVE生成 RDB 文件。这里要特别注意:BGSAVE是一个 fork 子进程的操作,会带来额外的内存和磁盘开销。如果主节点内存很大(比如 10GB 以上),fork 操作可能造成主节点短暂阻塞,这也是大内存实例做全量复制的风险点。
第三步是命令传播。RDB 文件发送完成后,主节点会把复制积压缓冲区中新增的写命令持续发送给从节点,从节点执行这些命令来同步数据。
关于复制积压缓冲区(repl_backlog),有一个非常重要的参数:repl-backlog-size。它决定了一个从节点断开重连后,能否走高效的增量复制而不是全量复制。如果缓冲区太小,从节点断开的时间稍微长一点,缓冲区的数据就被覆盖了,只能全量重传。在节点较多的集群中,频繁全量重传会对主节点造成巨大压力,所以这个参数要根据网络状况和写 QPS 合理设置。我的实践经验是:从节点重连窗口想在 5 到 10 分钟内覆盖,通常要配置成 64MB 到 256MB 以上,具体要结合写入速率来计算。
4.2 哨兵机制:故障发现与自动切换的完整闭环
主从复制只解决了数据冗余的问题,没解决“主节点挂了谁来接管”的问题。哨兵(Sentinel)机制就是来解决这个问题的。
哨兵是一个独立运行的 Redis 服务,它的核心职责有三块:监控、通知、自动故障转移。
监控方面,哨兵会定期向所有主节点和从节点发送PING命令来检测存活状态。如果一个哨兵发现主节点在down-after-milliseconds配置的时间内没有响应,它会将该主节点标记为“主观下线”。注意“主观”这个词,因为单个哨兵可能误判(比如哨兵自身网络抖动)。
为了减少误判,Redis 提供了“客观下线”判定机制。多个哨兵之间会互相通信,当一个哨兵判定主节点主观下线后,它会向其他哨兵发送询问,其他哨兵确认该主节点也不可达后,投票达到quorum值,才将其标记为“客观下线”。
客观下线之后,哨兵集群会发起一次选举,选出一个 leader 哨兵来执行故障转移。故障转移的逻辑包括:从所有从节点中选出一个新的主节点,让其他从节点改为复制新主节点,最后把旧主节点的信息更新为从节点,等它恢复后自动变成新主节点的从节点。
4.3 脑裂问题的本质与对策
关于哨兵机制,最容易被忽略的坑是脑裂问题。脑裂的意思是:主节点没有真的宕机,只是网络分区导致它和哨兵及大部分从节点失联了。哨兵认为主节点挂了,提升了一个新的主节点。但旧主节点还在运行,客户端还在往旧主节点写数据。
此时整个系统就有两个“主节点”在同时接收写请求,网络恢复后,旧主节点会被强制降级为新主节点的从节点,并清空自己本地的数据,重新做全量同步。这意味着脑裂期间写入旧主节点的数据全部丢失。
在架构设计上,脑裂不是完全不能防治,但只能缓解。Redis 提供了两个参数:min-replicas-to-write和min-replicas-lag。它们的含义是:主节点在写入前,至少要保证有多少个健康的从节点连着它,并且从节点的数据延迟不超过多少秒。如果从节点数量不足或延迟过大,主节点就拒绝写入。
这个机制的原理是:脑裂发生时,旧主节点通常失去了大部分从节点,所以min-replicas-to-write的约束会触发,让旧主节点停止写入,从而避免数据丢失。但这个方案的代价是:在主从网络有瞬时抖动时,可能会导致正常的写入也被拒绝,牺牲了可用性。这也是一个典型的一致性优先于可用性的配置场景。
注意:
min-replicas-to-write和min-replicas-lag只能缓解脑裂问题,不能根治。根治脑裂需要应用层配合,比如写操作加上当天时间戳或唯一 ID,在网络异常时可以识别出“新主”和“旧主”的数据差异,再做补偿。这是架构师要有的兜底思维。
5. 集群架构设计详解:Redis Cluster 的分片与重定向
5.1 哈希槽:数据分布的核心机制
Redis Cluster 是 Redis 官方的分布式解决方案,它通过数据分片把数据分散到多个主节点上,从而突破单机内存和单点吞吐的限制。
Cluster 的分片粒度不是简单的哈希取模,而是引入了哈希槽(Hash Slot)的概念。整个集群被划分为 16384 个槽位,每个 key 通过CRC16(key) % 16384计算得到一个槽位编号。每个主节点负责一部分槽位,比如一个三主节点的集群,槽位可以分配为:节点 A 负责 0-5460,节点 B 负责 5461-10922,节点 C 负责 10923-16383。
设计者选择 16384 这个数字是有考量的。第一,它足够大,可以让集群在水平扩展时数据分布比较均匀。第二,它又不是特别大,节点间的槽位迁移和心跳同步信息的体积都控制在合理范围内。16K 个槽位用位图表示,也就是 2KB 的数据,集群节点之间传播槽位信息非常高效。如果你去了解过这个决策的背景,会发现最初版本曾考虑过 65536 个槽位,但最终选定了 16384,是一个性能和扩展性的平衡点。
5.2 客户端路由与 MOVED 重定向
现在想一个问题:客户端要读一个 key,它怎么知道该连哪个节点?
Redis Cluster 的每个节点都保存了完整的槽位映射表,客户端连接到任意一个节点,发送命令时,该节点会计算 key 对应的槽位。如果槽位恰好由自己负责,就直接处理;如果不是,就返回一个MOVED错误,告诉客户端应该连接的节点地址。
标准的 Redis 客户端(比如 Java 的 Lettuce、Jedis,Python 的 redis-py)都实现了槽位缓存机制。它们会从集群中获取槽位映射表,缓存在本地,然后直接路由到正确的节点。如果集群发生了槽位迁移,客户端可能会收到ASK重定向,这时客户端需要向目标节点发送ASKING命令后重试。这两种重定向的区别是:MOVED表示槽位已经永久迁移,客户端应该更新自己的缓存映射;ASK表示槽位正在迁移过程中,客户端需要临时处理。
从架构师视角看,理解这两个重定向的差异非常重要,因为很多运维事故发生在槽位迁移期间:一些客户端没有正确处理ASK重定向,导致大量请求失败。这虽然不是 Redis 本身的问题,但架构设计时一定要选对客户端版本,并做好压测。
5.3 集群扩容与缩容:槽位迁移的完整流程
集群不会一直不变,业务增长了要扩容,流量下降了要缩容。Redis Cluster 支持在线增加节点和减少节点,核心操作就是槽位迁移。
扩容大致分四步:
- 新节点加入集群,使用
CLUSTER MEET命令让节点间建立握手。 - 通过
CLUSTER ADDSLOTS命令为空闲的槽位指定归属,或者更推荐redis-cli --cluster reshard在线迁移。 - 执行槽位迁移:数据从旧节点迁移到新节点,期间客户端可能收到
ASK重定向。 - 迁移完成后,更新集群的槽位映射表。
缩容的流程正好相反:先把需要下线的节点上的槽位迁移到其他节点,确认数据全部迁走后,再执行CLUSTER FORGET让节点退出集群。
这里有一个实操建议:槽位迁移是耗时的高风险操作,一定要在业务低峰期做,并且迁移前要做好数据备份。原因是迁移过程中每个 key 需要从源节点序列化、传输、反序列化写入目标节点,如果 key 很大(比如大 Value 的 String 类型),单个 key 的迁移会阻塞该槽位的服务。
5.4 Cluster 模式下的 IO 与内存管理要点
Cluster 模式下,架构师还要额外关注以下三个要点:
第一个是节点数量的规划。Cluster 推荐的最小规模是 3 主 3 从,因为至少要 3 个主节点才能组成一个可用的集群(投票和故障转移需要多数派)。生产环境我建议每个分片都要配一个从节点,否则主节点挂了,这个分片的槽位就完全不可用了。
第二个是大 Key 问题。在单机模式下,一个大 Key(比如几十 MB 的列表)只是占内存多一些。但在 Cluster 模式下,大 Key 会造成槽位迁移耗时、集群节点间数据不均衡、请求阻塞等多重问题。所以 Cluster 架构设计时,必须提前做好大 Key 的治理策略,比如拆分、压缩、换成哈希结构等。
第三个是批量操作的限制。因为 key 分散在不同槽位上,MGET、MSET这类多 key 操作只有在所有 key 都在同一个槽位时才能执行。实践中如果要批量读取大量不同槽位的 key,客户端需要做聚合多次请求,复杂度增加了不少。架构师在设计接口时要考虑到这个限制,尽量避免跨槽位的批量操作。
6. 技术选型实战:业务场景下高可用与集群的决策指南
6.1 从业务规模倒推架构方案
前面把理论和组件都讲了,现在进入最关键的部分:实操中怎么选型。我总结了一套从业务规模倒推架构方案的思路,已经在多个项目中验证过,可以直接套用。
如果你的数据量在 10GB 以内,QPS 在几万以下,挂一台 16GB 内存的机器就够了,配合一个从节点做备份,再加上哨兵做自动切换,这就是一个很完备的高可用架构。这套方案的优势是架构简单、运维成本低、故障排查容易,适合中小型项目或业务的初期阶段。
如果你的数据量到了几十 GB 到几百 GB,单机内存已经放不下,或者单点 QPS 已经扛不住,这时候就需要上 Cluster 了。起步推荐 3 主 3 从,共 6 个节点。总内存可以支撑几百 GB 的数据量,吞吐量也能提升好几倍。随着业务增长,后续可以平滑扩容到 6 主 6 从甚至更多。
还有一种中间状态:数据量不大但读 QPS 极高(比如热点数据被疯狂读取),这种场景应该优先考虑读写分离架构:一个主节点负责写入,挂多个只读从节点分摊读流量。Redis 的主从复制天然支持这个模式,客户端通过哨兵或代理层把读请求路由到从节点即可。但要注意,从节点的数据有延迟,不能接受读到旧数据的业务就不适合读从库。
6.2 一致性需求决定架构形态
选型的另一个重要维度,是对一致性的容忍度。
我经常用一个简单的判断方法:如果这个缓存中数据丢失了,用户能不能感知?业务能不能接受?如果答案是“不能接受”,你就不应该用异步复制的主从架构来承载这份数据,而应该把数据放在数据库里,Redis 只做加速;如果答案是可以接受,那么主从架构和最终一致性的方案就可以放心使用。
还有一个常见的设计是“双读双写”或“Cache Aside 模式”:业务先查缓存,缓存没有再查数据库,然后把结果写回缓存。这种模式下,缓存允许失效,缓存允许短暂不一致,Redis 的主从和哨兵架构完全够用。但如果业务逻辑依赖缓存中的值做决策(比如“如果某 key 存在就执行 A,否则执行 B”),就需要特别注意缓存和数据库之间的一致性问题,这时架构成熟度要求就完全不一样了。
6.3 代理方案与原生 Cluster 的取舍
除了原生的 Redis Cluster,市面上还有一些代理型方案(如基于 Proxy 的中间件),它们对客户端屏蔽了集群的复杂性,让客户端像使用单机 Redis 一样使用集群。这个方案适合什么场景呢?我个人的经验是:如果你的团队对 Redis Cluster 的机制不熟,或者客户端语言生态不完善,用代理方案会更稳妥。代理层帮你处理了槽位路由、数据分片、故障转移,但代价是多一跳网络开销,并且代理本身会成为性能和可用性的单点。
反过来说,如果你团队里有熟悉 Redis 底层的同学,我更推荐直接用原生 Cluster。它的性能更好,故障处理更透明,可运维性更强。而且现在主流的客户端库对 Cluster 的支持已经非常成熟了,踩坑成本大幅下降。从长期架构演进来看,原生 Cluster 是更值得投入的方向。
7. 常见问题与排查技巧实录
7.1 故障速查表:主从切换后数据不一致怎么办
我在维护 Redis 生产环境的过程中积累了不少排查经验,这里整理成一份速查表,遇到问题可以快速对照。
| 现象 | 可能原因 | 排查方向 | 解决方案 |
|---|---|---|---|
| 主从切换后部分数据丢失 | 异步复制窗口内写入的数据未同步 | 检查复制偏移量差、min-replicas-lag配置 | 关键业务启用 WAIT,或增加同步确认机制 |
| 从节点同步延迟持续增大 | 主节点写 QPS 过高或大 Key 阻塞 | 查看INFO replication中 lag 字段 | 降低主节点写压力,拆分大 Key,扩容从节点 |
| 哨兵误判主节点下线 | 网络抖动、哨兵自身负载过高 | 查看哨兵日志、down-after-milliseconds配置 | 调整阈值,增加哨兵数量至 3 个以上 |
| 集群节点间大量 MOVED 重定向 | 客户端槽位缓存过期 | 检查客户端库版本和槽位刷新机制 | 升级客户端库,检查异常路由日志 |
| 槽位迁移期间大量请求超时 | 大 Key 迁移阻塞、客户端未处理 ASK | 检查迁移日志和慢查询 | 拆分大 Key,错峰迁移,升级客户端 |
7.2 大 Key 和热 Key:Cluster 下最隐蔽的性能杀手
Cluster 架构下,最隐蔽的性能杀手就是大 Key 和热 Key。
大 Key 指的是单个 key 的 Value 特别大,比如一个包含上百万元素的 Hash、Set,或者一个几十 MB 的 String。大 Key 会导致的问题包括:删除操作阻塞 Redis(早期版本DEL大 Key 是同步的,会卡住整个节点)、迁移耗时增加、内存不均。
我处理过一个典型案例:某个列表 key 积攒了几十万个元素,每次对它做LRANGE全量操作都要耗时好几秒,直接把节点 CPU 打满,影响同节点其他 key 的请求。最后的方案是把这个列表拆分成多个小的列表 key,再通过时间戳分段访问,问题才彻底解决。
热 Key 指的是某个 key 的访问量特别大,把所有流量都打在一个节点上。热 Key 在单机时代问题不大,但在 Cluster 模式下,流量不均衡会导致某个分片过载。解决方案包括:给热 Key 增加随机后缀分散到多个节点(读多写少场景适用),或者在应用层做多级缓存,用本地内存挡掉一部分热点流量。
7.3 架构设计自检清单
最后,分享一份我在做 Redis 架构设计评审时经常使用的自检清单。每次方案设计完,照着清单过一遍,能避免大量低级错误:
- 单节点内存是否超过物理内存的 60%?如果超过,RDB 持久化和 fork 操作会导致阻塞风险。
- 主从复制的积压缓冲区大小是否覆盖了最长容忍的故障恢复时间?
- 哨兵数量是否大于等于 3,且部署在不同物理机上?
- 业务是否能接受主从切换期间的数据不一致窗口?是否有补偿机制?
- 数据量是否已经需要水平扩展?如果需要,每个分片的主从是否都齐全?
- 大 Key 和热 Key 是否已经有治理方案?
- 客户端版本是否支持 Cluster 的重定向语义?
- 是否有监控系统覆盖主从延迟、节点内存、QPS、慢查询等核心指标?
这套清单我建议打印出来贴在工位上,每次做架构设计时拿出来对照一遍,比自己凭记忆去翻文档要稳妥得多。
我自己在负责的多个项目里,第一版 Redis 方案几乎都是“单机 + 从库 + 哨兵”起步,直到数据量确实撑不住了才上 Cluster。不盲目追求最复杂的架构,而是在每个阶段选择最匹配当下业务的方案,这才是架构师的核心能力。这个决策过程看起来平淡,但它才是真正拉开架构师之间差距的地方。后续我会继续写 Redis 分布式架构的第二篇,深入讲讲缓存一致性、穿透、击穿、雪崩的实战应对,以及大规模集群的监控运维细节。