缓存击穿,双缓存处理策略

 

 

微信公众号:molashaonian

缓存击穿

某一个热点 key,在缓存过期的一瞬间,同时有大量的请求打进来,由于此时缓存过期了,所以请求最终都会走到数据库,造成瞬时数据库请求量大、压力骤增,甚至可能打垮数据库。

场景:商品列表,商品详情展示销量,库存等

大多解决方案

  • 加互斥锁。在并发的多个请求中,只有第一个请求线程能拿到锁并执行数据库查询操作,其他的线程拿不到锁就阻塞等着,等到第一个线程将数据写入缓存后,直接走缓存。

  • 热点数据不过期。直接将缓存设置为不过期,然后由定时任务去异步加载数据,更新缓存。

缺点:两种方案问题是能解决,但不是很漂亮,会产生阻塞,增加额外处理资源问题

双缓存处理策略

对于热点 key 可以设置一级,二级缓存;二级缓存可以设置较长的过期时间(甚至不过期),当一级缓存过期时,加锁从数据库中获取最新值,并且更新一级,二级缓存;同时没获得锁的线程直接读取二级缓存返回。

Syntax error in textmermaid version 11.4.1
Syntax error in textmermaid version 11.4.1
Syntax error in textmermaid version 11.4.1

代码实现

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
Alt

posted on   EvanLong  阅读(124)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2018-05-06 绝对完全跨域统一单点登录登出

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示