前言:为什么Redis总是面试官的"心头好"?(真实案例分享)
最近帮朋友做模拟面试,发现但凡涉及分布式系统的岗位,Redis相关问题是必考题!!!特别是当面试官开始推眼镜、身体前倾的时候(懂的都懂),大概率要出Redis的杀手级问题了。今天咱们就掰开揉碎聊聊那些让候选人"闻风丧胆"的Redis必问难题,文末还会分享我前同事靠Redis知识点逆袭拿下35k offer的真实案例!
一、Redis持久化连环炮(90%会被问到)
问题1:RDB和AOF到底怎么选?生产环境混用会翻车吗?
经典坑点:很多教程只会说"AOF更安全",但实际生产环境比这复杂100倍!去年我们线上就因为这个配置不当导致数据丢失(血的教训啊)。
正确姿势:
- 混合持久化配置(Redis4.0+):
# 必须同时开启这两个配置!!! aof-use-rdb-preamble yes save 900 1 # 根据业务量调整
- 内存计算器:每1GB内存,RDB fork耗时约15ms(千万要注意这个配置!)
问题2:AOF重写期间服务会挂吗?如何避免业务抖动?
真实案例:某电商大促期间因为AOF重写导致接口超时,直接损失300万订单!
解决方案:
- 设置
aof-rewrite-incremental-fsync yes
(减少磁盘压力) - 使用
INFO persistence
监控重写进度 - 业务低峰期手动执行
BGREWRITEAOF
(运维必杀技)
二、缓存击穿/穿透/雪崩灵魂三连(区分清楚才算入门)
问题3:布隆过滤器解决穿透问题,误判率怎么破?
反直觉真相:布隆过滤器不是银弹!我们做过测试,当元素量级达到1亿时,0.1%的误判率会让客服电话被打爆…
工程级方案:
// 双重校验锁+本地缓存(Guava Cache实现示例) public Object getData(String key) { Object value = redis.get(key); if (value == null) { if (bloomFilter.mightContain(key)) { // 布隆过滤器预判 synchronized (this) { // 二次检查防止并发穿透 value = db.get(key); redis.setex(key, 300, value); } } } return value; }
问题4:热点Key突然失效,如何避免百万级QPS压垮DB?
阿里云最佳实践:
- 本地缓存+Redis多级缓存(注意缓存穿透)
- 随机过期时间:基础过期时间+随机数(比如300~360秒)
- 永不过期策略+异步更新(适合极端热点数据)
三、分布式锁的魔鬼细节(面过字节的都懂)
问题5:Redlock算法真的安全吗?Redis作者和分布式专家吵起来了!
惊天大瓜:Martin Kleppmann(《数据密集型应用设计》作者)和Redis作者Antirez就Redlock的安全性展开过世纪论战!
共识结论:
- 适合非金融场景(比如抢优惠券)
- 必须配合token机制(防止误删)
- 建议使用:
set key random_value nx ex 30
- 更推荐使用Zookeeper/etcd做强一致性锁
四、集群方案生死局(回答不好直接挂)
问题6:Redis Cluster扩容时数据迁移卡死怎么办?
血泪教训:某公司迁移2TB数据时,因为cluster-node-timeout
设置不当导致集群脑裂!
迁移checklist:
- 分批迁移slot(每次不超过100个)
- 设置
cluster-migration-barrier 1
- 监控带宽使用率(推荐使用
iftop
)
五、底层原理致命拷问(P7以上必考)
问题7:Redis的ziplist为什么比普通list省内存?
源码级解析:
- 连续内存结构(CPU缓存友好)
- 通过
<prevlen> <encoding> <content>
三元组实现 - 字段长度动态调整(但会导致连锁更新问题)
问题8:为什么Redis单线程还能扛10万QPS?
颠覆认知:
- 多路复用epoll(C10K问题的经典解法)
- 内存操作纳秒级响应
- 避免上下文切换开销
- pipeline批处理(但要注意单个命令体积)
六、实战场景设计题(总监面必考)
问题9:如何用Redis实现滴滴的司机接单系统?
设计要点:
- GEOADD维护司机位置
- 使用HyperLogLog统计区域订单量
- 用Sorted Set实现接单优先级
- Pub/Sub通知新订单
七、终极拷问:Redis6.0多线程模型(答对薪资+5k)
问题10:多线程后还会有阻塞问题吗?
技术内幕:
- 仅网络IO多线程(执行命令还是单线程)
- 需要设置
io-threads 4
(建议是CPU核数的3/4) - 依然要避免
keys *
等危险操作
避坑指南:这些Redis错误写法你中招了吗?
- 在Lua脚本里写死循环(直接拖垮整个实例)
- 把Redis当数据库用(突然宕机数据全丢)
- 使用
expireat
但没同步服务器时间(鬼知道什么时候过期) - 大Value不拆分(导致慢查询)
结语:Redis学习的三个境界
- 青铜:会set/get
- 黄金:懂持久化/集群
- 王者:能根据业务特性定制数据结构(比如用zset实现延迟队列)
最后送大家一句话:Redis用得好,年终奖翻倍不是梦!但要是用不好…(你懂的)快去检查你们的Redis配置吧!