集群、哨兵、缓存模式与 Valkey
基于 Redis 7.x · 核于 2026-08
速查
- 主从复制(replication):一主多从,主写从读,异步复制(主写完立即回客户端,再批量发从)。用途:①读写分离分摊读流量;②数据冗余备份。异步 = 主挂可能丢未同步的写,不保证强一致。
- Sentinel(哨兵):独立部署的监控进程(至少 3 节点,奇数),监控主从存活,主挂时自动选举新主并通知客户端切换。提供自动故障转移(HA),但不分片(数据仍在一个主上,容量受单机内存限制)。
- Cluster(集群):分片 + 高可用一体。**16384 个槽位(slot)**平均分到各主节点,key 经
CRC16(key) % 16384落槽,节点间用 gossip 协议通信,客户端可连任意节点(不是该节点负责的 key 会返回MOVED重定向)。每个主可配从节点做故障转移。单 Cluster 上限 1000 主节点。 - cache-aside(旁路缓存,最常用):应用先查缓存,未命中查 DB 回填。应用负责维护一致性(写 DB 后删/更新缓存)。简单可控,推荐默认选型。
- write-through(穿透写):应用只写缓存,缓存同步写 DB(缓存层负责)。强一致但写延迟高(要等 DB)。
- write-back/write-behind(回写):应用只写缓存,缓存异步批量刷 DB。写极快但缓存挂会丢数据,适合容忍丢失的高写场景(计数、日志)。
- 缓存穿透(cache penetration):查根本不存在的数据(如恶意攻击用不存在的 ID),每次都穿到 DB。对策:①缓存空值(短过期);②布隆过滤器(前置拦截不存在的 key)。
- 缓存击穿(cache breakdown):单个热 key 过期瞬间,海量请求同时穿到 DB。对策:①互斥锁(只让一个请求查 DB 回填,其他等待);②热点 key 永不过期(后台异步更新)。
- 缓存雪崩(cache avalanche):大量 key 同时过期或 Redis 宕机,请求全打到 DB。对策:①过期时间加随机值避免同时失效;②多级缓存(本地 + Redis);③限流降级;④Redis 高可用(Sentinel/Cluster)。
- 2024 许可变更:Redis 7.4 起(2024 年 3 月宣布)从 BSD 改为 RSALv2/SSPL 双协议——不再被 OSI 认可为「开源」。云厂商、部分企业需评估合规。
- Valkey:Linux 基金会 2024 年 fork 自 Redis 7.2.4 的分支,AWS/Google/Oracle/Oracle/SNAP 联合背书,保留 BSD 许可。AWS ElastiCache、Google Memorystore 已转向 Valkey。Redis 7.4+ 与 Valkey 命令兼容,但未来可能分化。新项目选型要权衡。
一、主从复制:读写分离与冗余
Redis 主从复制是一主多从的架构:主(master)负责写,从(replica,旧称 slave)复制主的数据并负责读:
客户端(写) 客户端(读)
│ │
▼ ▼
┌───────┐ 异步复制 ┌───────┐ 异步复制 ┌───────┐
│ 主 │ ──────────▶ │ 从1 │ ◀────────── │ 从2 │
│master │ │replica│ │replica│
└───────┘ └───────┘ └───────┘- 全量同步(full resync):从节点首次连主,主执行
BGSAVE生成 RDB 发给从,从 load RDB 后,主再把期间的增量命令发给从。开销大(fork + 网络 + load)。 - 增量同步(partial resync):从节点断线重连后,若断线期间主的写命令还在**复制积压缓冲区(repl-backlog)**内,只需同步增量,不必全量。配置
repl-backlog-size(默认 1MB,大流量要调大)。 - 异步的代价:主写完立即回客户端,不等从确认——所以主挂时,未同步到从的写会丢。这是 Redis 复制「不保证强一致」的根本原因,也是为什么 Redis 通常不当金融强一致的真相源。
- 用途:读写分离(读多写少场景把读分摊到从)、数据冗余(主挂从还有数据)。注意:从节点默认会拒绝写(
replica-read-only yes),强行开从可写会导致数据不一致(从的写不会被同步)。
二、Sentinel:自动故障转移
Sentinel(哨兵)是 Redis 自带的高可用方案——独立部署一组监控进程,盯主从集群,主挂了自动选新主:
- 部署:至少 3 个 Sentinel 节点(奇数,防脑裂),独立于 Redis 实例部署(可共机但建议分离)。
- 监控:Sentinel 之间互相通信,每个 Sentinel 周期性 ping 主从与其他 Sentinel,判断存活(主观下线
SDOWN/ 客观下线ODOWN)。 - 故障转移:主被判定下线后,Sentinel 之间投票(Raft)选出一个 leader 主持转移;leader 从从节点里按优先级选一个提升为新主;通知其他从复制新主;通知客户端切换连接。
- 客户端:客户端连 Sentinel(不是直连 Redis),从 Sentinel 查当前主地址,主切换后 Sentinel 通知客户端。主流客户端(jedis/lettuce/redis-py)都内置 Sentinel 支持。
- 局限:Sentinel 只解决高可用,不分片——数据仍在一个主节点上,容量与写吞吐受单机内存与 CPU 限制。要横向扩展容量必须上 Cluster。
三、Cluster:分片与高可用一体
Cluster 是 Redis 的分布式方案,把数据分片到多个主节点,每个主带从节点做高可用:
┌─────────────────────────────────────────────────┐
│ 16384 个槽位(slot 0-16383) │
│ 槽位 0-5460 │ 槽位 5461-10922 │ 槽位 10923-16383 │
└─────────┬──────────┴────────┬──────────┴────────┬─────────┘
▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐
│ 主 A │ │ 主 B │ │ 主 C │
└───┬───┘ └───┬───┘ └───┬───┘
│ │ │
┌───┴───┐ ┌───┴───┐ ┌───┴───┐
│ 从 A' │ │ 从 B' │ │ 从 C' │
└───────┘ └───────┘ └───────┘- 槽位(slot):Cluster 有 16384 个槽,平均分配到各主节点。每个 key 经
CRC16(key) % 16384算出槽号,落到对应主节点。一个槽只属于一个主,所以 key 分布决定负载。 - hash tag:要让多个 key 落同一槽(便于在同一个节点上用 MGET/MULTI/Lua),用
{}包裹相同子串,如user:{1000}:profile和user:{1000}:order都按user:{1000}的 CRC16 落槽。 - gossip 协议:节点间周期性交换集群状态(谁在线、谁的槽、主从关系),最终一致。客户端可连任意节点,若 key 不在该节点负责的槽,返回
MOVED <slot> <ip:port>重定向,客户端缓存槽映射后下次直连。 - 高可用:每个主可配一个或多个从节点。主挂时,从节点中被选为新主(类似 Sentinel 但内嵌)。
- 限制:①只支持单 key 命令的跨槽(MSET/MULTI/Lua 涉及多 key 必须同槽);②不支持跨节点事务;③不支持 SELECT db(默认只用 db0)。单 Cluster 推荐上限 1000 个主节点。
- 何时用 Cluster:数据量超单机内存(如几百 GB)或写吞吐超单机上限时才上 Cluster——小规模用主从 + Sentinel 更简单。
四、缓存模式:cache-aside vs write-through vs write-back
应用用 Redis 当缓存时,写 DB 与写缓存的时序关系决定一致性、性能、可靠性的取舍:
| 模式 | 写流程 | 一致性 | 性能 | 风险 |
|---|---|---|---|---|
| cache-aside(旁路) | 写 DB → 删缓存 | 最终一致 | 高(写不碰缓存) | 删缓存失败会不一致(用消息补偿) |
| write-through(穿透) | 写缓存 → 缓存同步写 DB | 强一致 | 低(写要等 DB) | 写延迟高 |
| write-back(回写) | 写缓存 → 缓存异步刷 DB | 弱一致 | 极高 | 缓存挂丢数据 |
- cache-aside(旁路缓存,推荐默认):读时先查缓存,未命中查 DB 回填;写时先写 DB 再删缓存(删而不是更新,避免并发写导致缓存与 DB 不一致)。简单可控,是绝大多数业务的默认选择。
- write-through:应用只感知缓存,缓存层同步把写落到 DB。强一致,但每次写都要等 DB,延迟高。适合一致性要求高、写量不大的场景。
- write-back(write-behind):应用只写缓存立即返回,缓存层异步批量把变更刷到 DB。写极快,但缓存挂掉会丢未刷的数据。适合容忍丢失的高写场景(点击计数、行为日志)。
三大缓存问题与对策
| 问题 | 触发 | 后果 | 对策 |
|---|---|---|---|
| 穿透(penetration) | 查不存在的数据(恶意攻击) | 每次穿到 DB | 缓存空值(短过期)/ 布隆过滤器前置拦截 |
| 击穿(breakdown) | 热 key 过期瞬间 | 海量请求同时穿到 DB | 互斥锁(只一个查 DB)/ 热点永不过期 + 异步更新 |
| 雪崩(avalanche) | 大量 key 同时过期或 Redis 宕机 | DB 被压垮 | 过期时间加随机值 / 多级缓存 / 限流降级 / 高可用 |
五、2024 许可变更与 Valkey 分支
2024 年 3 月,Redis 官方(Redis Ltd.)宣布从 Redis 7.4 起把许可从 BSD 改为 RSALv2(Redis Source Available License v2)/ SSPL(Server Side Public License)双协议——不再被 OSI 认可为「开源」。这是继 MongoDB(SSPL)、Elastic(ELv2)之后又一数据库厂商转向「源码可见但限制云厂商」的许可。
- 为什么改:Redis Ltd.(原 RedisLabs)认为云厂商(AWS 等)拿开源的 Redis 赚钱却不回馈,改许可阻止云厂商提供托管 Redis 与其商业服务竞争。
- 影响:①云厂商提供 Redis 托管服务需评估合规;②部分企业(如禁用非 OSI 开源许可的)需评估是否仍能用 Redis 7.4+;③个人开发者与绝大多数自部署不受影响(RSALv2 允许内部使用、SaaS 使用,只是禁止把 Redis 本身作为服务卖给他人)。
- Valkey 分支:2024 年 3 月,Linux 基金会 fork 自 Redis 7.2.4 创建 Valkey,保留 BSD 许可。AWS、Google Cloud、Oracle、Snap 等联合背书,AWS ElastiCache、Google Memorystore 已转向 Valkey。Valkey 8 起独立演进。
- 选型建议:①新项目、追求纯开源与多供应商 → Valkey;②已在用 Redis 7.2 及以前(BSD)→ 可继续用;③要 Redis 7.4+ 新特性且接受 RSALv2 → 用 Redis;④用云托管(AWS/Google)→ 默认已是 Valkey 或有 Valkey 选项。两者命令高度兼容(Valkey fork 自 Redis 7.2.4),但未来会分化,选型前确认生态(客户端库、运维工具)支持情况。
下一步
掌握了数据结构、持久化、集群、缓存模式与许可变更后,下一步看参考——命令速查、数据结构选型表、持久化对比、缓存问题对策汇总、易错点清单,作为日常查阅与面试复习的速查手册。