缓存击穿,双缓存处理策略
微信公众号:molashaonian
缓存击穿
某一个热点 key,在缓存过期的一瞬间,同时有大量的请求打进来,由于此时缓存过期了,所以请求最终都会走到数据库,造成瞬时数据库请求量大、压力骤增,甚至可能打垮数据库。
场景:商品列表,商品详情展示销量,库存等
大多解决方案
-
加互斥锁。在并发的多个请求中,只有第一个请求线程能拿到锁并执行数据库查询操作,其他的线程拿不到锁就阻塞等着,等到第一个线程将数据写入缓存后,直接走缓存。
-
热点数据不过期。直接将缓存设置为不过期,然后由定时任务去异步加载数据,更新缓存。
缺点:两种方案问题是能解决,但不是很漂亮,会产生阻塞,增加额外处理资源问题
双缓存处理策略
对于热点 key 可以设置一级,二级缓存;二级缓存可以设置较长的过期时间(甚至不过期),当一级缓存过期时,加锁从数据库中获取最新值,并且更新一级,二级缓存;同时没获得锁的线程直接读取二级缓存返回。
代码实现
public List<GoodsRespDTO> findGoodsList() {
String key = "page:homepage:goods";
List<GoodsRespDTO> respDto = myRedis.get(key);
if(respDto != null) {
return respDto;
}
// 双缓存机制,加锁更新缓存
Lock lock = myRedis.getLock(key + ":update");
if (lock.tryLock(-1, 5000)) {
try {
// 查询数据库逻辑
respDto = selectMySQL();
if(respDto != null) {
// 更新一级缓存
myRedis.set(key, respDto, 3000);
// 更新二级缓存
myRedis.set(key + ":L2Cache", respDto, 8500);
}
return respDto;
}
} finally {
lock.unLock();
}
}
// 二级缓存
return myRedis.get(key + ":L2Cache");
}
微信公众号:molashaonian
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2018-05-06 绝对完全跨域统一单点登录登出