Redis作为当前最流行的分布式缓存数据库,几乎是后端面试的必考内容。面试官通常会从缓存问题、数据类型、分布式锁、持久化等几个维度进行考察。本文结合常见面试题,系统梳理核心知识点和解决方案。
一、缓存三大难题:穿透、雪崩、击穿
1. 缓存穿透
现象:查询一个根本不存在的数据,缓存层没有命中,请求直接打到数据库。如果恶意攻击者大量请求不存在的key,数据库可能会被压垮。 解决方案:
- 布隆过滤器:将所有可能存在的数据哈希到一个足够大的bitmap中,请求到来时先判断key是否存在,不存在则直接返回。优点是节省内存,缺点是有一定的误判率。
- 缓存空对象:如果数据库查询结果为空,仍然将空结果缓存(设置较短的过期时间),避免反复查询数据库。
2. 缓存雪崩
现象:大量缓存同时过期,或者Redis宕机,导致大量请求涌向数据库,造成数据库压力激增甚至崩溃。 解决方案:
- 缓存过期时间加随机值:避免大量key在同一时间过期,例如在基础过期时间上增加1-5分钟的随机值。
- 使用集群高可用:通过Redis Sentinel或Cluster模式保证Redis服务高可用,避免单点故障。
- 限流降级:在数据库访问层增加限流措施,保护数据库不被突发流量冲垮。
3. 缓存击穿
现象:一个热点key在失效的瞬间,大量并发请求同时访问该key,导致数据库压力瞬间增大。与雪崩的区别在于击穿是单个key失效,雪崩是大量key失效。 解决方案:
- 互斥锁(Mutex):当缓存失效时,只允许一个线程去查询数据库并重建缓存,其他线程等待。可以使用Redis的SETNX命令实现分布式锁。
- 逻辑过期时间:在缓存中存储一个逻辑过期时间字段,当发现逻辑过期时,只允许一个线程去更新缓存,其他线程返回旧数据。这种方式避免了加锁等待。
二、分布式锁实现
Redis分布式锁是面试高频考点,核心是使用SETNX命令(SET if Not eXists)加锁,同时设置过期时间防止死锁。解锁时使用Lua脚本保证原子性:先判断锁是否属于自己,再删除。
Redlock算法:Redis官方推荐的分布式锁方案,通过在多个Redis实例上同时加锁,只要大多数节点加锁成功就算成功,提高了锁的容错性。但实际生产中使用较少,因为实现复杂且性能开销大。
最佳实践:推荐使用Redisson客户端,它封装了可重入锁、读写锁等高级功能,并提供了看门狗机制自动续期,避免锁过期导致业务未完成。
三、数据类型与使用场景
Redis支持五种基本数据类型:
- String:最常用,可用于计数器、分布式锁(SETNX)、缓存对象(JSON字符串)。
- Hash:适合存储对象,如用户信息,可以单独更新某个字段。
- List:双向链表,可用于消息队列(LPUSH+BRPOP)、最新列表。
- Set:无序集合,支持交并补运算,适合标签系统、共同好友。
- ZSet:有序集合,每个元素带score,适合排行榜、延时队列。
四、持久化机制
- RDB(快照):按时间间隔生成全量数据快照,恢复速度快,但可能丢失最近的数据。适合备份和灾难恢复。
- AOF(追加文件):记录每次写操作命令,数据更安全,但文件体积较大。可以通过重写机制压缩。
- 混合持久化(Redis 4.0+):结合RDB和AOF,RDB做全量快照,AOF记录增量,兼顾恢复速度和数据安全。
五、总结与面试建议
面试时,不仅要能说出解决方案,还要理解背后的原理和适用场景。例如:缓存穿透时,布隆过滤器适合数据量大的场景,而缓存空对象适合数据量小的场景。分布式锁要重点说明原子性和死锁避免。
建议在简历中突出Redis的实际应用经验,比如用ZSet实现排行榜、用分布式锁解决库存超卖等问题。掌握这些核心知识点,面试Redis环节就能游刃有余。


