Easton Notes
八股Redis 面试题

过期淘汰与高可用

Redis 过期删除、内存淘汰、主从复制、哨兵故障转移与 Cluster 分片机制。

过期删除和内存淘汰有什么区别?

回答重点

两者解决的问题和触发条件不同:

机制触发条件处理对象目的
过期删除Key 到达 TTL,且被访问或被后台过期任务检查到已过期的 Key回收失效数据
内存淘汰实例内存达到 maxmemory,新命令需要继续占用内存由 maxmemory-policy 选出的 Key在内存上限内继续服务

Key 到达过期时间后会在逻辑上失效,但其内存不一定在同一时刻被回收。相反,被内存淘汰的 Key 不一定已经过期;淘汰策略可能删除仍在有效期内的数据。

因此,TTL 是数据生命周期设计,maxmemory 与淘汰策略是容量保护机制,两者不能互相替代。

Redis 的过期 Key 会立即删除吗?

回答重点

通常不会。Redis 主要组合使用两种策略,在 CPU 消耗和内存回收速度之间取平衡:

  • 惰性删除:访问 Key 时检查它是否过期;如果过期,就删除并按不存在处理。
  • 定期删除:后台周期性地从设置了过期时间的 Key 中采样,删除已过期项;如果样本中过期比例仍然较高,会在时间预算内继续检查。

Redis 不会为每个 Key 创建一个到点执行的定时器,也不会每轮扫描全部 Key。前者会增加定时器维护成本,后者可能长时间占用主线程。采样数量、执行频率和时间预算属于版本与配置相关的实现细节,不应背成固定常量。

扩展知识

过期时间只是“最晚从业务视角失效”的约束,不是精确的物理回收时刻:

  • 客户端读取已过期 Key 时,不会得到旧值。
  • 未再次访问且暂未被后台任务采样到的 Key,可能短暂占用内存。
  • 删除大对象本身也可能耗时,可结合 lazy free 配置或 UNLINK 把内存释放工作交给后台线程。
  • TTL 应按业务容忍的陈旧时间设置,不能只依赖内存淘汰兜底。

Redis 有哪些内存淘汰策略,应该如何选择?

回答重点

Redis 的常见 maxmemory-policy 可分为三组:

范围策略含义
不淘汰noeviction不主动淘汰;无法继续分配内存的写命令返回错误,读和部分不增加内存的命令仍可执行
仅有 TTL 的 Keyvolatile-lru淘汰近似最久未使用的 Key
仅有 TTL 的 Keyvolatile-lfu淘汰近似最少访问的 Key
仅有 TTL 的 Keyvolatile-random随机淘汰
仅有 TTL 的 Keyvolatile-ttl优先淘汰剩余生存时间更短的 Key
全部 Keyallkeys-lru在全部 Key 中淘汰近似最久未使用的 Key
全部 Keyallkeys-lfu在全部 Key 中淘汰近似最少访问的 Key
全部 Keyallkeys-random在全部 Key 中随机淘汰

选择时先判断数据是否允许丢失:

  • 纯缓存且访问热度差异明显,可优先评估 allkeys-lfu。
  • 一般缓存、近期访问更能代表未来访问时,可评估 allkeys-lru。
  • 同一实例混放可淘汰和不可淘汰数据时,可用 volatile-* 只淘汰带 TTL 的 Key,但没有合适候选时写入仍会失败。
  • 数据不能被自动删除时使用 noeviction,同时必须做好容量规划、扩容和写入失败处理。

扩展知识

Redis 的 LRU 和 LFU 是基于采样的近似算法,不会维护全量精确排序。近似算法减少了额外内存和维护成本,但意味着被淘汰的不一定是理论上的最优 Key。

不要等到刚好触达 maxmemory 才告警。复制缓冲区、客户端输出缓冲区、持久化时的写时复制和内存碎片都需要额外空间,应结合命中率、淘汰量、内存水位和写入错误持续监控。

Redis 主从复制的全量同步和增量同步如何实现?

回答重点

主从复制通常先由副本向主节点发送 PSYNC,携带复制 ID 和复制偏移量。主节点据此决定全量同步还是增量同步。

全量同步主要用于首次复制,或者主节点无法从复制积压缓冲区提供副本缺失的数据:

  1. 主节点返回 FULLRESYNC,告知当前复制 ID 和偏移量。
  2. 主节点生成 RDB 快照,也可以按配置使用无盘复制直接传输快照。
  3. 生成和传输快照期间,主节点继续处理写命令,并缓存需要发送给副本的命令流。
  4. 副本接收快照,清理旧数据并载入 RDB。
  5. 主节点再把快照期间积累的写命令发给副本,之后进入持续命令传播阶段。

增量同步主要用于短暂断线后的续传:

  1. 副本重连后通过 PSYNC 上报已有的复制 ID 和偏移量。
  2. 如果复制 ID 匹配,并且缺失区间仍在主节点的复制积压缓冲区中,主节点返回 CONTINUE。
  3. 主节点发送缺失的命令字节,副本追平后继续接收实时命令。
  4. 如果所需数据已被环形缓冲区覆盖,或者复制 ID 无法衔接,就退化为全量同步。

扩展知识

需要区分两个概念:

  • 复制积压缓冲区是主节点维护的环形历史窗口,用于判断和提供断线后的增量数据。
  • 副本输出缓冲区用于保存尚未发送给某个副本的数据,慢副本可能导致该缓冲区持续增长。

复制积压缓冲区可按“峰值写入字节速率 × 希望容忍的断线时间”估算并留出余量。全量同步会带来 fork、写时复制、磁盘或网络传输以及副本加载数据的开销,应避免因缓冲区过小而频繁触发。

Redis 主从和 Cluster 能保证强一致性吗?

回答重点

通常不能。Redis 主从复制默认是异步的:主节点执行写命令并回复客户端时,副本可能尚未收到该命令。如果此时主节点故障并发生切换,尚未复制的已确认写入可能丢失。读取副本也可能读到旧数据。

Redis Cluster 的每个分片内部同样依赖主从复制和故障转移,因此也存在这个窗口。不能仅用“属于 AP”概括所有运行状态,更准确的表达是:Redis 优先提供高性能和可用性,但默认复制与故障转移协议不提供线性一致性承诺。

扩展知识

可以缩小风险窗口,但不能把它们包装成强一致性:

  • WAIT 可以让客户端等待指定数量的副本确认已接收此前写入,但超时、故障转移和持久化边界仍需单独处理。
  • min-replicas-to-write 与 min-replicas-max-lag 可在健康副本不足时拒绝写入,以可用性换取更低的数据丢失概率。
  • 关键数据仍应由支持所需事务与一致性语义的数据库作为事实来源,Redis 更适合缓存、派生状态和可恢复的加速数据。

Sentinel 如何判断故障并完成主从切换?

回答重点

Sentinel 负责监控、自动故障转移、通知和主节点地址发现,本身不负责数据分片。典型流程如下:

  1. 主观下线:某个 Sentinel 在配置时间内没有收到主节点的有效响应,将其标记为 S_DOWN。这是该 Sentinel 的本地判断。
  2. 客观下线:该 Sentinel 询问其他 Sentinel;认为主节点下线的数量达到配置的 quorum 后,将主节点标记为 O_DOWN。
  3. 选举故障转移领导者:Sentinel 使用纪元和投票选出本轮执行者。成为领导者不仅要满足 quorum,还要获得 Sentinel 多数票,两者不要混为一谈。
  4. 选择新主节点:排除长期断连或状态异常的副本,再依次考虑副本优先级、复制进度和运行 ID 等条件。
  5. 重配置与通知:提升选中的副本,让其他副本复制新主节点,并向客户端发布新主节点信息。

副本优先级配置中,replica-priority 为 0 表示永不晋升;其他条件相同时,数值更小的副本优先,而不是数值越大越优先。复制偏移量越大通常表示数据越新。

扩展知识

生产环境通常部署至少三个 Sentinel,并放在不同故障域。Sentinel 解决的是“谁成为主节点”和“客户端去哪里连接”,不能消除异步复制导致的数据丢失,也不能替代业务侧的重试、幂等和一致性设计。

Redis Cluster 如何通过哈希槽分片和重定向请求?

回答重点

Redis Cluster 把键空间划分为 16384 个哈希槽。普通 Key 的槽位计算可表示为:

slot = CRC16(key) mod 16384

每个主节点负责一部分槽,副本用于该主节点故障后的切换。客户端从任意集群节点获取“槽位到节点”的映射并缓存在本地;访问 Key 时先计算槽位,再直接请求负责该槽的节点。Redis Cluster 节点通常返回重定向,不充当通用请求代理。

客户端访问了错误节点或遇到槽位迁移时,会收到两类响应:

  • MOVED:槽位已经由另一个节点负责。客户端应向目标节点重试,并刷新本地槽位映射。
  • ASK:槽位正在迁移,本次请求应临时去目标节点。客户端先向目标节点发送 ASKING,再执行原命令,但不应仅凭 ASK 永久改写槽位归属。

扩展知识

涉及多个 Key 的原子命令、事务或 Lua 脚本,通常要求这些 Key 位于同一槽。可以用哈希标签让一组 Key 使用花括号中的相同内容计算槽位,例如:

order:{1001}:detail
order:{1001}:items

Cluster 通过分片扩展容量和吞吐,通过副本与投票完成分片故障转移,但仍有约束:

  • 跨槽多 Key 操作受限。
  • 槽位迁移和故障切换期间,客户端必须正确处理重定向与重试。
  • 某个主节点及其副本都不可用时,对应槽会不可用;是否进一步阻断整个集群取决于槽覆盖配置。
  • 异步复制意味着故障切换仍可能丢失少量已确认写入,Cluster 不等于强一致性系统。

评论

On this page