复习定位
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