前言:Redis为什么是必考题?
(别以为面试官都问基础命令!)现在稍微有点规模的互联网公司,哪个不用Redis搞缓存/队列/分布式锁?我亲眼见过候选人能把Redis五种数据类型倒背如流,结果问到主从同步原理直接懵逼…(血泪教训啊兄弟姐妹们!)
一、持久化机制连环杀
问题1:RDB和AOF到底怎么选?
这题90%的人只会背"RDB全量/AOF增量",但实际生产环境要考虑的远不止这些!
核心差异点:
- 数据恢复速度:RDB快照恢复速度是AOF日志的10倍以上(实测过!)
- 数据安全性:AOF的appendfsync配置不同,丢数据范围在1秒~完全不丢
- 性能影响:RDB的bgsave会导致瞬间CPU/内存飙升(特别是在大内存实例)
实战场景决策树:
- 需要定期归档数据 ➔ RDB
- 金融交易类系统 ➔ AOF everysec + RDB每日备份
- 缓存场景允许丢失 ➔ 关持久化 + 主从复制
问题2:混合持久化真的靠谱吗?
(Redis4.0的新特性,但坑也不少!)先看原理图:
[重启时]
加载RDB快照 → 重放AOF增量
优势:
- 综合了RDB的快速恢复 + AOF的数据完整性
- AOF文件比纯AOF模式小很多(只记录增量)
坑点预警:
- 内存碎片问题会更严重(长期运行后)
- 首次开启时会生成双份持久化文件(磁盘空间要预留够!)
二、缓存穿透/雪崩/击穿三大杀器
问题3:布隆过滤器的误判率怎么计算?
(数学公式恐惧症患者慎入!)公式推导过程咱们跳过,直接说结论:
当存储100万数据,布隆过滤器用3个哈希函数时:
- 分配1.7MB内存,误判率≈1%
- 内存增加到2.5MB,误判率能降到0.1%
代码实战技巧:
from redisbloom.client import Client
rb = Client()
# 初始化过滤器(关键参数别搞错!)
rb.bfCreate('hotel_filter', 0.01, 1000000)
# 批量添加时用管道提升性能
pipe = rb.pipeline()
for hotel_id in hotel_ids:
pipe.bfAdd('hotel_filter', hotel_id)
pipe.execute()
问题4:热点Key突然失效怎么办?
(某电商大促真实事故还原!)当百万QPS的热点Key同时失效,数据库直接被打穿…
防御组合拳:
- 互斥锁 + 双重检测(老套路但有效)
- 本地缓存 + 随机过期时间(应对缓存雪崩)
- 热点Key标记 + 后台线程定期续期(阿里开源的解决方案)
三、分布式锁的魔鬼细节
问题5:Redlock算法真的绝对安全吗?
(Redis作者和分布式专家吵过架的问题!)Antirez的Redlock方案曾被Martin Kleppmann质疑,核心争议点在于:
时钟跳跃风险:
- 客户端1获取锁后发生GC停顿
- 锁超时释放 → 客户端2获得锁
- 此时两个客户端都认为自己持有锁
行业最佳实践:
- 对时钟一致性要求高的场景 ➔ 改用Zookeeper
- 一般业务场景 ➔ Redlock + 自动续期
- 极端情况 ➔ 业务层做幂等补偿
四、高频刁钻问题汇总
问题6:为什么Redis单线程还这么快?
(别再只说内存操作了!)深层原因包括:
- 基于Reactor模式的网络模型
- 避免上下文切换开销(对比Memcached多线程)
- 渐进式Rehash机制(扩容时不阻塞)
问题7:大Key删除的正确姿势
(直接del命令会卡死服务!)分步操作:
- 用scan命令拆分key
- 每次删除100条 + sleep 1ms
- 4.0+版本可用UNLINK异步删除
五、压轴题:Redis多线程演进
问题8:6.0版本的多线程改进了什么?
(注意!不是完全多线程!)架构图解析:
主线程:处理命令执行、网络IO
IO线程池:专门处理读写socket(默认4个)
性能提升实测:
- 单实例QPS从10w提升到20w+
- 但CPU核心数超过8个时提升不明显
- 集群模式下的扩展性更好
最后叮嘱(必看!)
最近面试发现很多同学在Redis问题上栽跟头,不是知识点没背熟,而是缺乏场景化思考能力。比如:
- 让你设计一个延迟队列,能不能说出多种方案对比?
- 主从切换时如何处理脑裂问题?
- 集群模式下的数据倾斜怎么排查?
(建议拿出你项目中的Redis使用场景,用上面的知识点重新分析一遍,绝对会有新收获!)