软考高级系统架构师之Redis篇

系统架构师学习平台(点击这里进入)

⚡ Redis 核心指南

Redis (Remote Dictionary Server) — 开源、基于 Key-Value 的内存 NoSQL 数据库,常作为 MySQL 前的高速缓存层

  • 🚀 10W+ QPS
  • 💾 持久化 RDB/AOF
  • 🔐 Redisson 分布式锁
  • 📊 面试高频

💡 一句话:Redis = 内存 + 单线程 + I/O多路复用,读写比磁盘快10~100倍,降低DB压力。

📚 一、数据类型 & 经典场景

类型 特点 典型场景
String 字符串/数值,原子增减 缓存、计数器、分布式锁(setnx)
Hash 键值对嵌套 (field-value) 购物车、用户对象存储
List 双向链表,有序可重复 消息队列、最新评论列表
Set 无序不可重复,集合运算 抽奖(spop)、共同好友(sinter)
ZSet 按分数排序,唯一 排行榜、延时队列

✨ 特殊类型

  • 🗺️ Geo
    附近的人 / 门店距离
  • 📊 HyperLogLog
    日活UV统计 (0.81%误差)
  • 🎯 Bitmap
    签到 / 在线状态 / 布隆过滤器基础

⚠️ 二、缓存三兄弟 · 穿透|击穿|雪崩

🔍 缓存穿透

问题: 查询不存在的数据,请求绕过缓存直达DB,恶意攻击可能导致DB崩溃。
解决方案: ① 缓存空对象 (短期TTL);② 布隆过滤器 (位图+多个hash,高效拦截不存在Key,允许小概率误判)。

💥 缓存击穿 (热点key过期)

问题: 高并发下热点key失效,大量请求同时打到数据库。
解决方案: ① 热点key永不过期(逻辑过期);② 互斥锁 (分布式锁),仅允许一个线程重建缓存。

🌊 缓存雪崩

问题: 大量key同时过期 或 Redis宕机,瞬时流量压垮数据库。
解决方案: ① TTL加随机值;② Redis集群高可用;③ 多级缓存;④ 限流/熔断。

📖 记忆口诀:穿透无中生有布隆挡,击穿过期锁与非期扛,雪崩大量过期加随机,三兄弟保底限流强。

🔄 三、缓存与MySQL一致性(双写)

数据变化时保证 Redis 与 DB 最终一致性的常见方案:

方案 实现方式 特点
先更DB + 删缓存 更新数据库后删除Redis缓存,读取时重建 简单,可能短暂不一致
延迟双删 先删缓存 → 更新DB → 延时再次删除 避免旧数据回写,延迟难控制
MQ异步通知 DB更新后发消息,消费者更新缓存 解耦、有重试,最终一致
Canal监听Binlog 伪装MySQL从库,读取binlog同步到Redis 无业务侵入,实时性高

选型建议: 强一致性业务直接查库;允许短暂不一致 → MQ/Canal 最终一致。

💾 四、持久化机制 (数据不丢失)

特性 RDB (快照) AOF (追加日志)
原理 定期生成全量二进制快照 dump.rdb 记录每条写命令到 appendonly.aof
恢复速度 快速(直接加载二进制) 慢(逐条重放命令)
数据安全 可能丢失最后一次快照后的数据 每秒刷盘最多丢1秒数据
性能影响 fork子进程,短暂阻塞 fsync策略影响IO

🚀 生产最佳实践:混合持久化 (RDB全量备份 + AOF增量补充)
配置: appendonly yes + appendfsync everysec + 合理RDB save规则。

⏳ 五、过期删除 & 内存淘汰

Redis采用:惰性删除 + 定期删除
▪ 惰性删除:访问key时检查过期则删除 → 节省CPU。
▪ 定期删除:每隔100ms随机抽查一批过期key → 平衡CPU与内存。

📌 内存淘汰策略 (达到maxmemory时)

策略 行为 推荐场景
volatile-lru 从设置过期时间的key中淘汰最近最少使用 大部分生产场景(有永久数据)
allkeys-lru 从全体key淘汰最近最少使用 纯缓存场景,数据可重建
volatile-lfu 淘汰访问频率最低的(设置过期) 热点数据倾斜
noeviction 不淘汰,内存满时写入报错(默认) 金融/支付强数据安全

💡 LRU = 最久未访问,LFU = 最少频率访问(带衰减机制)。

🔒 六、分布式锁(Redisson实现)

场景: 集群定时任务、抢券、扣库存 — 保证同一时刻只有一个线程执行。

原生Redis锁: SET lock value NX EX 10 + DEL,存在原子性隐患。
Redisson 改进:

  • ✅ Lua脚本保证 setnx+过期时间原子性
  • 可重入锁 (Hash结构存储线程ID+重入次数)
  • WatchDog看门狗:自动续期 (每10秒续期一次,避免业务未完成锁释放)
  • ✅ 自旋重试机制,提升性能
  • ⚠️ 主从切换可能导致锁丢失,强一致性建议用 ZooKeeper 锁

🐕 看门狗核心:锁持有后自动续期,业务完成需手动unlock,高并发下性能优越。

🌐 七、高可用 & 集群进化

📡 主从复制 (读写分离)

一主多从,主写从读。全量同步:首次连接 bgsave + RDB;增量同步:通过偏移量从复制积压缓冲区获取缺失命令。

👁️ 哨兵模式 Sentinel

监控 + 自动故障转移 + 通知客户端。解决主从手动切换。
⚠️ 脑裂问题:配置最少从节点个数和同步延迟阈值缓解。

🧩 分片集群 (Cluster)

解决海量数据+高并发写:
16384个哈希槽,每个key通过 CRC16(key)%16384 映射到槽,槽分布在多个主节点,水平扩展。
每个主节点可带从节点,自动故障转移。不支持跨槽事务,可用 {hash_tag} 强制同槽。

💡 生产建议:节点数 ≥ 3,副本数 ≥ 1,避免脑裂。结合哨兵实现高可用,海量数据选用Cluster。

⚡ 八、为什么Redis如此快?

  • ✅ 纯内存操作,读写极快
  • ✅ 单线程执行命令(6.0后IO多线程但命令仍单线程),避免上下文切换和竞态
  • I/O多路复用 (epoll):单线程同时监听多个socket,事件驱动不空转
  • ✅ 高效数据结构设计 & 渐进式rehash

🔧 Redis变慢了怎么排查?

  • 慢查询日志:slowlog get 查看复杂命令
  • 避免bigkey:--bigkeys 扫描,大key阻塞主线程
  • 大量key同时过期 → TTL添加随机值
  • AOF重写与磁盘竞争:配置 no-appendfsync-on-rewrite yes
  • 检查swap:INFO memory,若swap过大则增加内存/集群扩容

📌 九、Redis vs Memcache & 高频考点

对比维度 Memcache Redis
数据类型 仅字符串 丰富 (String/Hash/List/Set/ZSet等)
持久化 不支持,重启丢失 RDB+AOF混合持久化
高可用 无原生支持 主从/哨兵/集群
原子性 部分指令 单指令原子 + Lua保证多指令

💬 面试高频附加题:
• 数据库有1000w数据,Redis仅缓存20w热点 → 选用 allkeys-lruvolatile-lru 策略。
• Redis内存满了怎么办?取决于淘汰策略,默认 noeviction 直接报错。
• 布隆过滤器实现原理:位数组 + 多个hash函数,通过0/1快速判断“肯定不存在”,存在微小误判率。
• 缓存三兄弟解决方案汇总:穿透(布隆/空值)、击穿(互斥锁/逻辑过期)、雪崩(随机TTL/集群/限流)。

📖 十、速记汇总·一图流

  • 🏆 穿透
    布隆过滤器+空值缓存
  • 🏆 击穿
    互斥锁/逻辑永不过期
  • 🏆 雪崩
    随机TTL+集群+限流
  • 💾 持久化
    RDB快照 + AOF everysec
  • 🔁 淘汰策略
    allkeys-lru / volatile-lru
  • 📈 集群
    哨兵(高可用) → Cluster(水平分片)

🔥 总结:Redis基于内存、单线程+I/O多路复用成就高性能;生产环境务必配置合理淘汰策略+持久化,使用Redisson优雅解决分布式锁。

适用场景:缓存、分布式锁、排行榜、计数器、消息队列、Session共享、实时分析。


posted @ 2026-06-07 22:25  岩文01  阅读(27)  评论(0)    收藏  举报