Appearance
考点清单
- [x] Redis 5 种基本类型 + 3 种特殊类型
- [x] 缓存穿透/雪崩/击穿(现象 + 解决方案)
- [x] Redis 3 种过期策略(定时/惰性/定期)
- [x] Redis 8 种内存淘汰策略
- [x] RDB vs AOF 持久化机制对比
- [x] Redis 3 种高可用架构(主从/哨兵/Cluster)
- [x] Redis 分布式锁(SETNX → 看门狗 → Redlock)
- [x] Cache-Aside 模式读写流程 + 双写一致性
- [x] MySQL 分布式锁缺点
- [x] 基于 ZSet 的分布式锁命令
笔记
一、Redis 基础类型
五种基本类型:
| 类型 | 特点 |
|---|---|
| String | 最基本字符串类型 |
| Hash | key-value 结构(field-value 对),适合对象存储 |
| List | 有序可重复列表 |
| Set | 无序不可重复集合 |
| ZSet | 有序集合(带排序),考试重点(如排行榜),改版后考过相关命令 |
三种特殊类型:
| 类型 | 用途 |
|---|---|
| Geo | Redis 3.2+,存储地理位置信息 |
| HyperLogLog | 基数统计(如网站 UV 统计) |
| Bitmaps | 位图,单比特映射元素状态(类似操作系统位示图) |
二、缓存问题分析 ★
1. 缓存穿透
查询不存在的数据时,缓存和数据库均无记录,导致每次请求直达数据库。
解决方案:
| 方案 | 说明 |
|---|---|
| 参数校验 | API 入口过滤非法值 |
| 空值缓存 | 对空结果也缓存,设合理过期时间(需维护一致性) |
| 布隆过滤器 | 2022 考点,概率型数据结构快速判断存在性,空间效率极高 |
2. 缓存雪崩
大规模缓存失效引发数据库崩溃。场景:大量缓存同时过期 / Redis 集群整体故障。
| 解决方案 | 优点 | 缺点 |
|---|---|---|
| 过期时间随机化 | 实现简单 | 不能应对 Redis 宕机 |
| 缓存预热 | 热点数据命中率高 | 需维护热点列表 |
| 多级缓存 | 高性能、降低 Redis 依赖 | 本地缓存一致性问题 |
| Redis 高可用 | 避免单点故障 | 成本高、架构复杂 |
| 限流 & 降级 | 保护数据库 | 用户体验可能受影响 |
| 热点数据永不过期 | 命中率极高 | 数据可能过期不一致 |
生产环境:过期时间随机化 + Redis 集群高可用 + 多级缓存 + 限流降级组合使用。
3. 缓存击穿
单点热点 key 失效(vs 雪崩的大面积失效)。如秒杀商品、爆款新闻过期并发查询。
| 解决方案 | 说明 |
|---|---|
| 互斥锁 | 2024 考点,原子操作控制并发重建缓存 |
| 逻辑永不过期 | 设较长 TTL,异步线程监控热点 key 临近过期自动续期 |
| 集群分流 | Redis 集群分散读流量 |
| 多级缓存 | 本地缓存 + 分布式缓存多层结构 |
三、Redis 过期策略
| 策略 | 机制 | 优点 | 缺点 |
|---|---|---|---|
| 定时过期 | 每个 key 创建独立定时器,到期立即清除 | 内存友好 | 消耗大量 CPU |
| 惰性过期 | 仅在访问 key 时判断是否过期 | 节省 CPU | 过期 key 可能堆积 |
| 定期过期 | 每隔 ~100ms 随机抽取部分 key 检查 | 平衡 CPU 和内存 | 清理不够及时 |
生产环境默认:惰性过期 + 定期过期结合。
四、Redis 8 种内存淘汰策略 ★
| 策略 | 范围 | 算法 | 核心机制 |
|---|---|---|---|
| volatile-lru | 过期 key | LRU | 淘汰最近最少使用 |
| allkeys-lru | 所有 key | LRU | 全局淘汰冷数据 |
| volatile-lfu | 过期 key | LFU | 淘汰最不常用(Redis 4.0+) |
| allkeys-lfu | 所有 key | LFU | 全局频率淘汰 |
| volatile-random | 过期 key | 随机 | 随机淘汰 |
| allkeys-random | 所有 key | 随机 | 全局随机 |
| volatile-ttl | 过期 key | TTL | 淘汰即将过期 key |
| noeviction | 全局 | 无淘汰 | 内存满拒写报错(默认) |
生产环境优先
allkeys-lru或allkeys-lfu。
五、持久化机制 RDB vs AOF ★
| 对比 | RDB(快照) | AOF(追加日志) |
|---|---|---|
| 原理 | 定时生成内存快照 → dump.rdb | 记录每个写命令到 appendonly.aof |
| 触发 | 手动 save/bgsave,自动按时间 + 写次数 | always/everysec/no |
| 优点 | 文件小、恢复快、适合大规模备份 | 数据安全性高、准实时持久化 |
| 缺点 | 两次快照间可能丢数据 | 文件大、恢复慢 |
| 类比 | 全量备份 | 操作日志 |
生产:RDB + AOF 混合持久化(Redis 4.0+)。
六、高可用架构
| 模式 | 核心机制 | 优势 | 缺陷 |
|---|---|---|---|
| 主从模式 | Master 写 + Slave 读,读写分离,全量+增量复制,repl_backlog 断线续传 | 架构简单 | 主节点故障需人工切换 |
| 哨兵模式 | 多 Sentinel 心跳检测(PING),主观/客观下线,自动 failover(Redis 2.8+) | 自动故障检测与切换 | 部署复杂,全量副本 |
| Cluster 集群 | 16384 Hash Slot(CRC16+取模),Gossip 协议通信,302 重定向 | 可水平扩容,分布式存储 | 配置维护复杂 |
演进:主从 → 哨兵(自动故障转移)→ Cluster(分布式+在线扩容)。
- 小规模:主从 + 哨兵
- 中大规模:Redis Cluster
七、分布式锁演进 ★
| 方案 | 核心 | 缺陷 |
|---|---|---|
| SETNX + 过期时间 | SETNX key value 加锁,DEL key 解锁 | 单节点故障锁丢失;长事务过期失效 |
| 看门狗续期(Redisson) | 后台线程定期续期,默认每 10s | 仍依赖单节点 |
| Redlock 算法 | 多独立 Redis Master(通常 5 个),超半数加锁成功 + 耗时 < TTL | 实现复杂,网络延迟影响 |
演进:SETNX → 看门狗 → Redlock(多节点多数派原则)。
八、基于 ZSet 的分布式锁命令 ★
背记:ZADD 抢锁,ZREM 放锁,ZREMRANGEBYSCORE 清过期
| 操作 | 命令 |
|---|---|
| 获取锁 | ZADD lock_zset <score> <lock_id> |
| 释放锁 | ZREM lock_zset <lock_id> |
| 清理过期锁 | ZREMRANGEBYSCORE lock_zset -inf <current_timestamp> |
| 检查锁存在 | ZSCORE lock_zset <lock_id> |
九、MySQL 分布式锁缺点
- 性能瓶颈:每次锁操作需执行 SQL
- 单点故障:MySQL 宕机锁全部失效
- 死锁处理复杂:需额外死锁检测和超时机制
- 实现复杂度高:需手动编写 SQL + 事务
- 可扩展性差:难以应对大规模分布式系统
- 锁粒度控制困难:基于行/表,粒度较粗
十、Cache-Aside 模式
读流程:请求缓存 → 命中返回 → 未命中查 DB → 更新缓存 → 返回数据。
写流程:更新数据库 → 删除/失效缓存(使后续读取获取最新数据)。
双写一致性解决方案:
- 分布式锁(Redis SETNX):写前加锁,读写串行化
- 延迟双删:写库后删一次,延迟 500ms 再删一次
- 异步消息队列(Canal + Kafka):监听 binlog 异步失效缓存
- 版本号/逻辑时钟:缓存带版本,读时比对 DB 版本
十一、Redis 主从复制流程
全量同步(首次):从库发 PSYNC ? -1 → 主库返回 FULLRESYNC replid offset → 主库 bgsave 生成 RDB → 发送 RDB → 从库清空本地加载 RDB → 主库发送 repl_backlog 中命令。
增量同步(断线重连):从库发 PSYNC replid offset → 主库判断 replid 一致 → 回复 CONTINUE → 从 repl_backlog 读取 offset 之后的命令发送。