跳转至

Redis 缓存设计与高可用

本目录将 Redis 核心知识点拆分为独立文件,便于按需学习和复习。


知识点目录

序号 文件 内容概要
01 数据结构与底层编码 String/Hash/List/Set/ZSet 五种数据结构、底层编码切换原理、跳表 vs 红黑树
02 持久化机制 RDB 与 AOF RDB 快照、AOF 追加日志、混合持久化、持久化方案选型
03 缓存三大问题 缓存穿透(布隆过滤器)、缓存击穿(互斥锁/逻辑过期)、缓存雪崩(随机TTL/多级缓存)
04 高可用架构 主从复制、哨兵模式(自动故障转移)、集群模式(分片/16384 slot)
05 分布式锁 SETNX 手动实现的问题、Redisson 看门狗/可重入锁、RedLock 红锁
06 应用型问题 缓存一致性(Cache Aside/延迟双删/Canal)、排行榜/计数/限流/消息队列/Session 共享、大 Key 与热 Key 处理

1. Redis 解决了什么问题?

问题背景:没有 Redis 时,所有请求都直接打到 MySQL,高并发场景下会出现:

问题 具体表现 Redis 的解决方案
数据库压力大 热点数据每次都查 MySQL,连接数耗尽 热点数据缓存在内存,减少 DB 查询
响应速度慢 MySQL 磁盘 IO,毫秒级响应 内存读写,微秒级响应(快 10 万倍)
无法分布式协调 多实例无法共享锁、Session 分布式锁、分布式 Session
计数/排行榜复杂 数据库实现计数器、排行榜性能差 原子 INCR、ZSet 天然支持

2. Redis 在系统架构中的位置

flowchart LR
    Client[客户端] --> App[应用服务]
    App -->|缓存命中| Redis[(Redis\n内存缓存)]
    App -->|缓存未命中| MySQL[(MySQL\n持久化存储)]
    MySQL -->|回写缓存| Redis
    Redis -->|持久化| Disk[磁盘\nRDB/AOF]

3. 面试高频问题速查

Q:Redis 为什么这么快?

① 纯内存操作;② 单线程避免锁竞争;③ IO 多路复用(epoll);④ 高效的数据结构(跳表、压缩列表等)。注意:Redis 6.0 引入了多线程处理网络 IO,但命令执行仍是单线程。

Q:Redis 单线程为什么还这么快?

瓶颈在内存和网络 IO,不在 CPU。单线程避免了线程切换和锁竞争开销,反而更高效。Redis 的 QPS 可达 10 万+,对大多数业务场景已经足够。

Q:Redis 内存淘汰策略有哪些?

  • noeviction:不淘汰,内存满时报错
  • allkeys-lru:淘汰最近最少使用的 Key(最常用)
  • volatile-lru:只淘汰设置了过期时间的 Key 中最近最少使用的
  • allkeys-random:随机淘汰
  • volatile-ttl:淘汰剩余 TTL 最短的 Key

Q:Redis 过期 Key 是如何删除的?

惰性删除:访问时检查是否过期,过期则删除(节省 CPU,但可能内存泄漏);② 定期删除:每隔 100ms 随机抽取一批设置了过期时间的 Key 检查删除。两者结合使用,互补不足。


4. 一句话口诀

String 存缓存,Hash 存对象,List 做队列,Set 做去重,ZSet 做排行榜; 穿透用布隆,击穿用互斥锁,雪崩加随机 TTL; 高可用靠哨兵,扩容靠集群,分布式锁用 Redisson。


5. 工作中常见错误速查

场景 错误做法 正确做法
存储对象 用 String 存整个 JSON,更新时全量覆盖 用 Hash 存对象字段,按需更新单个字段
缓存过期 所有 Key 设置相同 TTL TTL 加随机偏移量(如 300 + random(60))
分布式锁 SETNX 后未设置过期时间 使用 SET key value NX PX milliseconds 原子命令
大 Key 存储几 MB 的 Value 拆分大 Key,或使用 Hash 分片存储
热 Key 单个 Key 承受所有流量 本地缓存 + Redis 多副本分散热点
跨 Slot Cluster 模式下 mget 多个 Key 使用哈希标签 {} 确保相关 Key 在同一 Slot