1. 课程导入与高可用全景
Redis 作为内存数据库,单机部署时存在明显的单点风险:进程崩溃、宿主机宕机、网络分区、磁盘故障、内存耗尽导致 OOM,都会让服务在数秒到数十分钟内不可用。所谓“高可用”,并不是让 Redis 永不故障,而是让系统在故障发生时,能够在可接受的时间内自动或半自动恢复读写能力,并把数据损失控制在业务可容忍的范围内。因此,Redis 高可用设计要同时回答三个问题:故障时谁来接管、数据能保留多少、客户端如何感知切换。
从故障场景看,可以按影响范围分为三类。第一类是单节点故障,例如主节点进程退出、机器断电、网卡异常,此时需要有一个已经同步了数据的副本被提升为新主节点。第二类是局部网络故障,例如主从之间网络抖动、哨兵与主节点失联,此时系统必须区分“节点真的挂了”和“只是网络不通”,否则容易发生误切换甚至双主。第三类是数据与容量故障,例如主节点内存写满触发 maxmemory 淘汰、AOF/RDB 文件损坏、持久化失败,这类问题往往不会立刻表现为连接失败,但会持续影响写入与恢复能力。不同故障对应的恢复手段不同,这也是三种主流方案定位不同的根本原因。
Redis 高可用方案可以归纳为三条技术路线:主从复制、哨兵(Sentinel)、集群(Cluster)。主从复制解决的是数据冗余与读扩展问题:一个主节点接收写请求,一个或多个从节点通过复制流同步数据,从节点可以分担读流量。但主从复制本身不解决自动故障切换,主节点挂掉后需要人工把某个从节点提升为主节点,并通知客户端修改连接地址。哨兵在主从复制之上增加了监控、判断、选举和自动故障转移能力,适合单主多从、数据量可控、希望自动切换的场景。集群则通过分片把数据分散到多个主节点,每个主节点再带从节点,既解决容量与吞吐扩展,也提供分片级别的故障转移,适合数据量大、写入吞吐高、可以接受多键操作受限的场景。
选型时不能只看“哪个更高级”,而要看业务约束。若数据量在单机内存可承受范围内,且希望架构简单、运维成本低,主从复制加人工切换或配合外部编排即可;若要求自动故障转移、客户端改动小、数据量仍在一台机器可容纳的范围内,哨兵是更自然的选择;若单机内存已经无法容纳全量数据,或者写入 QPS 超过单主节点上限,就必须考虑集群分片。需要注意的是,集群模式下跨 slot 的多键命令、事务和 Lua 脚本会受到限制,业务侧需要提前做 key 设计,例如使用 hash tag 把需要一起操作的 key 映射到同一 slot。
下面这张图把三种方案的定位、故障切换能力和典型适用边界放在同一张全景图中,便于在后续章节展开前先建立整体判断框架。
理解这张全景图后,后续章节会依次展开主从复制的同步机制、哨兵的监控与选举流程、集群的分片与重定向逻辑,以及故障切换过程中数据一致性与客户端行为的变化。本节先建立判断框架:主从复制是基础,哨兵解决自动切换,集群解决规模扩展。实际生产环境中,三者并非互斥,例如集群的每个分片内部仍然使用主从复制,哨兵也可以与主从复制组合使用。选型的核心不是追求最复杂的方案,而是让恢复时间目标(RTO)和恢复点目标(RPO)与业务要求匹配。