Redis
Redis
Redis 面试八股知识点总结 💡
1️⃣ Redis 的 5+3 种基本数据结构 📦
✅ String(字符串) 📌 应用场景:缓存 session
、token
、限流、分布式锁、计数器
✅ List(列表) 📌 应用场景:消息队列(LPUSH + BRPOP
)、时间线
✅ Hash(哈希表) 📌 应用场景:用户信息、购物车、对象存储
✅ Set(集合) 📌 应用场景:去重(点赞、共同好友、标签)
✅ ZSet(有序集合) 📌 应用场景:排行榜、延迟队列
💡 扩展数据结构: ✅ Bitmap:用户签到、活跃用户统计 ✅ HyperLogLog:UV 统计(节省内存但有误差) ✅ GEO:地理位置存储(查找附近的人)
2️⃣ Redis 如何实现高性能?🚀
✅ 内存存储:所有数据都存储在 内存 中,读写速度极快(纳秒级别)。 ✅ 单线程:避免 多线程加锁 造成的上下文切换开销。 ✅ IO 多路复用:基于 Reactor 模式,同时处理多个连接的请求。 ✅ Redis 6.0+ 引入 多线程,优化 网络 IO(命令解析 & 响应回写)。
❓ 为什么 Redis6.0 之前不采用多线程? 📌 Redis 的瓶颈主要在 网络 IO,而不是 CPU 计算。
3️⃣ Redis 过期删除策略 ⏳
✅ 过期删除(两种策略)
- 定时删除(定期扫描 & 批量删除,但占用 CPU 资源)。
- 惰性删除(访问时检查过期,不会主动删除,可能占用内存)。
✅ 内存淘汰策略(内存不足时启用) 📌 常见策略(适用于 设置了过期时间 的键):
- TTL(最近即将过期的先删除 ⏳)
- LRU(最近最少使用的优先删除 🕰️)
- LFU(最少访问的优先删除 📉)
- RANDOM(随机删除 🎲)
4️⃣ Redis 分布式锁 🔒
✅ 基于 SETNX + EXPIRE
实现(简单但有问题 ❌) ❌ 锁过期 & 误删问题:业务超时,锁过期被其他线程获取,原线程执行完后释放的是别人的锁。 ✅ 优化方案: 📌 1. 给锁加唯一标识(避免误删) 📌 2. 使用 Lua 脚本(保证解锁的原子性)
✅ Redisson 分布式锁(推荐 ✅) 📌 特性:可重入、自动续期(watchdog 机制)、支持锁重试、基于 Lua 脚本保证原子性。
✅ Zookeeper 分布式锁 📌 基于 临时顺序节点 + Watcher 机制,避免自旋等待,提高锁的公平性。
✅ RedLock(Redis 多节点分布式锁) 📌 用于 Redis 单点故障的情况下,但不能完全避免锁失效问题。
5️⃣ Redis 生产环境问题 🛠️
✅ 缓存穿透 🚨 📌 问题:查询数据库 & Redis 都没有 该数据,导致请求直接打到数据库,影响性能。 📌 解决方案:
- 参数校验 ❌ 非法请求直接拦截。
- 缓存空值(
value = null
),避免重复查询数据库。 - 布隆过滤器(BloomFilter),高效判断 Key 是否存在。
✅ 缓存雪崩 ❄️ 📌 问题:大量 Key 同时过期,请求打爆数据库。 📌 解决方案:
- 过期时间加随机值(防止集中失效)。
- Redis 集群,避免单点故障。
✅ 缓存击穿 💥 📌 问题:某个 热点 Key 失效,大量请求瞬间打爆数据库。 📌 解决方案:
- 互斥锁(加锁查询)。
- 设置热点 Key 永不过期,手动删除。
✅ BigKey & 热点 Key 📌 问题:大 Key 影响查询 & 删除性能;热点 Key 影响集群均衡。 📌 解决方案:
- 拆分大 Key(List 拆分多个小 Key)。
- 热点 Key 进行多级缓存(本地缓存/CDN/Redis Cluster)。
✅ 数据一致性问题 🔄 📌 问题:MySQL & Redis 数据不一致(延迟更新问题)。 📌 解决方案:
- 先更新数据库,再删除缓存(避免并发问题)。
- 延时双删策略(删除缓存 -> 更新数据库 -> 等待 -> 再次删除缓存)。
- MQ + Canal 监听 MySQL Binlog,实现缓存同步。
6️⃣ Redis 持久化机制 📝
✅ RDB(快照持久化) 📌 原理:周期性地将 整个 Redis 数据快照 持久化到磁盘。 📌 优点:文件小、恢复快。 📌 缺点:可能丢失最近一次快照后的数据。
✅ AOF(Append-Only File) 📌 原理:记录所有写操作,可重放日志恢复数据。 📌 优点:数据更安全,最多丢失 1 秒数据。 📌 缺点:日志文件较大,恢复速度较慢。
✅ 选择方案 📌 高性能但允许数据丢失:RDB ✅ 📌 数据安全但影响性能:AOF ✅ 📌 最佳方案:RDB + AOF 结合使用。
7️⃣ Redis 事务 & Lua 脚本 ⚡
✅ Redis 事务(MULTI
+ EXEC
) 📌 缺点:不支持回滚,只保证命令的顺序执行。
✅ Lua 脚本(推荐!) 📌 优点:
- 原子操作(Redis 一次执行完整的 Lua 脚本)。
- 减少网络开销(多个命令打包执行)。
8️⃣ Redis 集群 🏢
✅ 主从复制(Master-Slave) 📌 主库负责写入,从库负责读取(适合读多写少场景)。
✅ 哨兵模式(Sentinel) 📌 自动监控 Redis 状态,主库宕机自动切换从库。
✅ Redis Cluster(推荐!) 📌 采用数据分片(哈希槽),将数据存储到不同的节点,实现 高可用 & 可扩展性。
9️⃣ Redis 延迟队列 & 滑动窗口限流 📊
✅ 延迟队列(基于 ZSet
) 📌 用 ZADD
记录任务时间,定时轮询 ZRANGEBYSCORE
取出任务。
✅ 滑动窗口限流(基于 ZSet
) 📌 记录时间戳,每次请求时移除超出窗口范围的数据,统计剩余请求数。
🎯 总结:Redis 面试重点关注:高性能机制、数据一致性、分布式锁、持久化、集群架构、缓存优化! 🚀