第一板块:基础与原理 (必问)
Q1:Redis 为什么这么快?
-
纯内存操作:数据存储在内存中,读写速度非常快。
-
单线程模型:避免了多线程的上下文切换和竞争条件(没有锁的开销)。
-
IO 多路复用 :使用
epoll机制,单个线程高效处理多个网络连接请求。 -
高效的数据结构:如 SDS(简单动态字符串)、ZipList(压缩列表)、SkipList(跳表)等专门优化的结构。
Q2:Redis 的数据类型有哪些?应用场景是什么?
-
String:缓存、计数器、分布式锁。
-
List:消息队列、最新列表(栈/队列操作)。
-
Hash:存储对象(如用户信息),由于字段独立,修改方便。
-
Set:去重、交集/并集(共同好友、抽奖)。
-
ZSet (Sorted Set):排行榜、带权重的消息队列。
-
(加分项) Bitmap (签到/状态位)、HyperLogLog (基数统计,如UV)、Geo(地理位置)。
Q3:Redis 是单线程的吗?
-
核心业务单线程:处理网络 IO 和执行键值对读写命令是由一个主线程完成的。
-
辅助功能多线程:Redis 4.0 之后,异步删除(UNLINK)、持久化(BGSAVE)等操作是由后台子线程处理的。Redis 6.0 引入了多线程处理网络 IO(读写 Socket),但执行命令依然是单线程。
第二板块:持久化 (你刚学过)
Q4:RDB 和 AOF 的区别?如何选择?
| 特性 | RDB (快照) | AOF (日志) |
|---|---|---|
| 原理 | 全量备份,保存二进制数据 | 增量备份,保存写命令 |
| 恢复速度 | 快 | 慢 (需重放命令) |
| 数据安全性 | 低 (可能丢失最后一次快照后的数据) | 高 (最多丢 1 秒) |
| 文件体积 | 小 (压缩过) | 大 (文本追加) |
- 选择建议 :生产环境通常混合使用。开启混合持久化(Redis 4.0+),AOF 重写时前半段用 RDB 格式,后半段用 AOF 格式,兼顾速度与安全。
第三板块:高可用与集群 (进阶)
Q5:主从、哨兵、Cluster 集群的区别?
-
主从复制 :解决数据备份 和读写分离,但无法自动故障转移。
-
哨兵 (Sentinel) :解决高可用。监控主从状态,Master 挂了自动选新主(你刚才做的实验)。
-
Cluster 集群 :解决高并发写入 和海量数据存储。通过分片(Sharding)将数据分布在不同节点,去中心化。
Q6:Redis Cluster 是如何分片的?
-
Hash Slot (哈希槽):Redis Cluster 没有使用一致性哈希,而是引入了哈希槽概念。
-
16384 个槽:整个集群被分为 16384 个槽,每个节点负责一部分槽。
-
计算公式 :
CRC16(key) % 16384决定 key 放到哪个槽,从而决定去哪个节点。
第四板块:缓存异常 (地狱级难度,必背)
这三个问题是面试中的"重灾区",必须分清楚。
Q7:缓存穿透 (Penetration)?
-
现象 :查询一个不存在的数据(缓存没命中,数据库也没有)。导致每次请求都打到数据库,可能压垮 DB。
-
解决:
-
布隆过滤器 (Bloom Filter):请求前先判断是否存在。
-
缓存空对象 :数据库没查到也缓存一个
null,设置短一点的过期时间。
-
Q8:缓存击穿 (Breakdown)?
-
现象 :一个热点 Key(如秒杀商品)突然过期,此时大量并发请求瞬间击穿缓存,直接打到数据库。
-
解决:
-
互斥锁 (Mutex Lock):缓存失效时,只让一个线程去查 DB 并回写缓存,其他线程等待。
-
逻辑过期:数据永不过期,但在 Value 里存一个过期时间,异步线程去更新数据。
-
Q9:缓存雪崩 (Avalanche)?
-
现象 :大量 Key 在同一时间过期 ,或者 Redis 宕机。导致所有请求全部涌向数据库。
-
解决:
-
随机 TTL:给过期时间加一个随机值,避免同时过期。
-
Redis 高可用:搭建哨兵或集群。
-
限流降级:系统扛不住时,直接返回错误或默认值。
-
第五板块:过期与淘汰策略
Q10:Redis 的 Key 过期了,是立刻删除吗?(过期策略)
-
不是。Redis 采用 惰性删除 + 定期删除。
-
惰性删除:你去查这个 Key 的时候,Redis 检查一下,如果过期了就删掉。
-
定期删除:Redis 每隔一段时间(默认 100ms)随机抽取一些 Key 检查是否过期,过期则删。
-
Q11:内存满了怎么办?(内存淘汰策略)
当内存达到 maxmemory 限制时,会触发淘汰策略:
-
noeviction:默认策略,不删除,直接报错(写操作)。
-
allkeys-lru :所有 Key 中,移除最近最少使用的(最常用)。
-
volatile-lru:只在设置了过期时间的 Key 中,移除最近最少使用的。
-
(还有 Random 随机删除、LFU 最不经常使用等)
第六板块:分布式锁 (实战重点)
Q12:如何用 Redis 实现分布式锁?
-
基础命令 :
SET key value NX PX 30000(即:如果不存在则设置,并设置 30s 过期)。 -
问题:如果业务执行时间超过 30s,锁过期了怎么办?
-
进阶 :使用 Redisson 框架。它有一个 WatchDog (看门狗) 机制,会自动给锁"续期",直到业务执行完成。
-
红锁 (Redlock):解决 Redis 主节点挂掉导致锁丢失的问题(但在业界有争议,现在更多倾向于用 ZooKeeper 做强一致性锁)。