复习定位

Redis 面试重点是:为什么快、怎么做缓存、如何保证数据尽量不乱、故障时怎么兜底。不要只背五种数据类型。

Redis 为什么快?

常见原因:

  • 数据主要在内存里。
  • 核心命令执行模型简单,避免大量线程切换。
  • 使用 I/O 多路复用处理连接。
  • 数据结构为常见场景做了优化。

注意:Redis 单线程通常指命令执行主流程,不代表整个 Redis 进程没有其他后台线程。

常见数据类型

String

最常用,可以做缓存、计数器、分布式锁 value。

Hash

适合存对象字段,比如用户信息。字段级更新比整段 JSON 更细,但结构太复杂时也会增加维护成本。

List

有序链表结构,适合简单队列、时间线,但现在很多队列场景会优先考虑 Stream 或专门消息队列。

Set

无序去重集合,适合标签、共同好友、黑白名单。

ZSet

带分数的有序集合,适合排行榜、延时队列、按权重排序。

过期和淘汰

Redis 删除过期 key 通常结合惰性删除和定期删除。

内存不够时会按配置的淘汰策略处理,例如:

  • volatile-lru:从设置过期时间的 key 中按 LRU 淘汰。
  • allkeys-lru:从所有 key 中按 LRU 淘汰。
  • volatile-ttl:优先淘汰更快过期的 key。
  • noeviction:不淘汰,写入报错。

面试回答要区分:过期删除是 key 到期后的处理;内存淘汰是内存压力下的策略。

持久化

RDB

RDB 是快照持久化。优点是文件紧凑、恢复快;缺点是两次快照之间的数据可能丢失。

AOF

AOF 记录写命令。优点是数据丢失更少;缺点是文件可能更大,需要重写压缩。

实际生产可以结合使用:RDB 适合快速恢复,AOF 提高数据安全性。

缓存三大问题

缓存穿透

查询不存在的数据,请求每次都打到数据库。

常见处理:

  • 缓存空值并设置较短过期时间。
  • 布隆过滤器提前判断 key 是否可能存在。
  • 做参数校验和限流。

缓存击穿

某个热点 key 过期,大量请求同时打到数据库。

常见处理:

  • 热点 key 逻辑过期。
  • 互斥锁重建缓存。
  • 热点数据提前续期。

缓存雪崩

大量 key 同时过期或 Redis 故障,导致请求集中压到数据库。

常见处理:

  • 过期时间加随机值。
  • 多级缓存。
  • 限流降级。
  • Redis 高可用部署。

缓存一致性

常见策略是先更新数据库,再删除缓存。

为什么不是直接更新缓存?因为复杂对象缓存可能被多个业务路径修改,直接更新容易漏字段或并发覆盖。

删除缓存失败时可以配合重试队列、订阅 binlog 或延迟双删。没有绝对强一致,通常追求最终一致。

分布式锁

基础写法:

SET lockKey requestId NX PX expireMillis

要点:

  • NX 保证不存在才写入。
  • PX 设置过期时间,避免死锁。
  • value 用唯一标识,释放时只能删自己的锁。
  • 释放锁要保证判断和删除的原子性,通常用 Lua 脚本。

风险:业务执行时间超过锁过期时间,会出现锁提前释放。可以考虑续期机制,或者用成熟客户端。

主从、哨兵、集群

主从复制用于读扩展和备份。哨兵负责监控、故障转移和通知。Cluster 通过槽位分片把数据分散到多个节点。

面试里要说清楚:主从解决复制,哨兵解决自动故障转移,Cluster 解决水平扩展。

面试收束

Redis 高频题可以围绕四件事:快在哪里、缓存怎么用、异常场景怎么兜底、分布式场景如何控制一致性和可用性。

参考资料

  • JavaGuide:https://javaguide.cn/
  • JavaGuide GitHub:https://github.com/Snailclimb/JavaGuide