【Redis】缓存问题及解决方案

Redis 高并发实战:缓存问题 + 分布式锁 + 解决方案

📌 本篇核心目标:

  • 搞懂 Redis 在真实项目中"怎么用才不会出事"
  • 解决高并发场景的经典问题
  • 掌握面试高频"场景题"的标准回答

一、为什么 Redis 在高并发下会出问题?

很多人觉得:

text 复制代码
用了 Redis → 性能就稳了 ❌

现实是:

Redis 用不好 = 系统更容易崩


核心原因

text 复制代码
Redis = 缓存层(不是万能)

一旦缓存出问题:

流量会直接打到数据库(灾难)


二、三大缓存问题


1️⃣ 缓存穿透(Cache Penetration)


什么是缓存穿透?

查询一个不存在的数据

流程:

text 复制代码
请求 → Redis(没有)→ 数据库(也没有)→ 返回空

如果攻击者疯狂请求:

text 复制代码
DB 直接被打爆 

举个例子
text 复制代码
查询 userId = -1

数据库根本没有这个数据,但请求一直来。


✅ 解决方案(必须会)

方案一:缓存空值(简单有效)
java 复制代码
String user = redis.get("user:100");

if (user == null) {
    user = db.query();
    if (user == null) {
        redis.set("user:100", "null", 60); // 缓存空值
    }
}

方案二:布隆过滤器

本质:一个"存在性判断结构"

text 复制代码
存在 → 可能存在  
不存在 → 一定不存在

面试回答模板
text 复制代码
缓存穿透解决方案:

1. 缓存空值(简单)
2. 布隆过滤器(高并发推荐)

2️⃣ 缓存击穿(Cache Breakdown)


什么是缓存击穿?

一个热点 Key 突然过期

text 复制代码
高并发请求 → 同时打到数据库 

举例
text 复制代码
商品详情(爆款商品)

✅ 解决方案

方案一:互斥锁

只允许一个线程查数据库

java 复制代码
String value = redis.get("key");

if (value == null) {
    if (tryLock()) {
        value = db.query();
        redis.set("key", value);
        unlock();
    } else {
        Thread.sleep(50);
        retry();
    }
}

方案二:逻辑过期(高级方案)

key 不删除,而是:

text 复制代码
存一个"过期时间字段"

面试回答模板
text 复制代码
缓存击穿解决:

1. 加锁(互斥锁)
2. 逻辑过期(高性能方案)

3️⃣ 缓存雪崩(Cache Avalanche)


什么是缓存雪崩?

大量 key 同时过期


举例
text 复制代码
系统重启 → 所有缓存同时失效 

✅ 解决方案

方案一:随机过期时间(最常用)
java 复制代码
redis.set(key, value, 300 + random(100));

方案二:多级缓存
text 复制代码
Nginx → Redis → DB

方案三:限流降级

保护数据库


面试回答模板
text 复制代码
缓存雪崩解决:

1. 随机过期时间
2. 多级缓存
3. 限流降级

三、分布式锁


为什么需要分布式锁?

场景:

text 复制代码
秒杀系统 / 库存扣减

如果不用锁:

text 复制代码
超卖 ❌

1️⃣ Redis 实现分布式锁


✅ 正确写法
bash 复制代码
SET lock_key value NX EX 10

解释:

  • NX:不存在才设置
  • EX:过期时间(防死锁)

❗ 错误写法
bash 复制代码
SETNX + EXPIRE ❌(非原子操作)

2️⃣ 解锁问题(高频坑)


❌ 错误写法
java 复制代码
redis.del("lock");

可能误删别人的锁!


✅ 正确写法(Lua脚本)
lua 复制代码
if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

3️⃣ 分布式锁面试回答模板

text 复制代码
Redis 分布式锁核心:

1. SET NX EX 保证原子性
2. value 唯一(防误删)
3. Lua 脚本释放锁

4️⃣ 实战推荐

使用

text 复制代码
Redisson(官方推荐)

Redisson 示例

java 复制代码
RLock lock = redissonClient.getLock("lock");

lock.lock();

try {
    // 业务逻辑
} finally {
    lock.unlock();
}

四、热点 Key 问题


什么是热点 Key?

一个 key 被疯狂访问


问题

text 复制代码
Redis 单点压力过大

✅ 解决方案


1️⃣ 本地缓存(一级缓存)
text 复制代码
JVM缓存 + Redis

2️⃣ Key 分散
text 复制代码
user:1 → user:1_1 user:1_2

3️⃣ 读写分离

主从架构


五、Big Key 问题


什么是 Big Key?

👉 一个 key 很大(比如 100MB)


问题

  • 阻塞 Redis
  • 网络慢

✅ 解决方案

  • 拆分 key
  • 控制 value 大小
  • 使用合适数据结构

六、实战总结


如果面试官问:

"Redis 在高并发下会有哪些问题?"


✅ 标准回答:

text 复制代码
Redis 在高并发场景主要有:

1. 缓存问题:
   - 穿透
   - 击穿
   - 雪崩

2. 分布式锁问题:
   - 原子性问题
   - 锁误删问题

3. 热点 Key / Big Key 问题

七、项目回答模板


场景题:

"你项目中 Redis 怎么用?"


✅ 参考回答:

text 复制代码
我们项目中 Redis 主要用于缓存热点数据,

同时针对高并发场景做了优化:

1. 使用随机过期时间防止缓存雪崩
2. 使用互斥锁解决缓存击穿
3. 使用布隆过滤器防止缓存穿透
4. 使用 Redis 分布式锁保证数据一致性

八、总结


text 复制代码
Redis 高并发核心问题:

1. 缓存三大问题(穿透/击穿/雪崩)
2. 分布式锁(SET NX EX + Lua)
3. 热点 Key / Big Key
相关推荐
always_TT2 小时前
字符串输入:gets vs fgets(安全问题)
数据库·安全
我科绝伦(Huanhuan Zhou)2 小时前
【生产案例】MySQL InnoDB 数据损坏崩溃修复
数据库·mysql·adb
猹叉叉(学习版)2 小时前
【系统分析师_知识点整理】 3.数据库系统
数据库·笔记·软考·系统分析师
6+h3 小时前
【Redis】高可用核心讲解
数据库·redis·缓存
海棠蚀omo3 小时前
从零敲开 MySQL 的大门:库与表的基础操作实战(保姆级入门指南)
数据库·mysql
鸽芷咕3 小时前
告别迁移焦虑:KingbaseES如何搞定Oracle复杂的层次查询与伪列?
数据库·oracle
当代红领巾3 小时前
Oracle 中的物理备份
数据库·oracle
007张三丰3 小时前
常用缓存技术全方位解析:从本地缓存到分布式缓存
分布式·缓存