ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

记一次缓存击穿的解决

2022-07-14 13:31:19  阅读:146  来源: 互联网

标签:缓存 过期 击穿 redis 接口 二级缓存 更新 解决


参考:
Redis 缓存雪崩、缓存穿透、缓存击穿、缓存预热
《我们一起进大厂》系列-缓存雪崩、击穿、穿透
一行代码解决缓存击穿问题

先看下缓存击穿的概念:

缓存击穿指的是某个热点缓存,在某一时刻恰好失效了,然后此时刚好有大量的并发请求,此时这些请求将会给数据库造成巨大的压力,这种情况就叫做缓存击穿。

说下我遇到的问题:

项目中需要请求其他远程接口的数据,这些数据会在本地接口处理一些请求的时候被使用。

首先避免频繁请求远程接口拿数据,先做个缓存:本地接口处理请求时优先查缓存,没有再请求接口获取数据并更新。

以上逻辑很简单常用,但考虑到我使用了缓存数据的本地接口可能会有很大的并发,如果缓存没有或者失效的情况,就会有很多并发线程同时去请求远程接口,给远程接口造成很大的压力,同时影响了本地接口的响应速度。

下面说下解决思路:

1、加锁排队。

优先查缓存,查不到缓存,就使用redis锁更新缓存。

redis锁:向redis写入更新缓存开始的标记,同时请求远程接口并更新缓存,更新完毕清除redis的标记。其他线程如果查到redis标记存在,就while True阻塞等待直到查出缓存。

该方法的缺点是阻塞了本地接口的并发处理,可能带来潜在问题。

2、逻辑过期时间

缓存设置永不过期,在写入缓存数据时加上生成时间和有效时间,读取缓存时判断时间是否过期,如果过期,就加上redis标记去更新缓存(保证同时只有一个线程更新缓存),其他线程检查到redis更新缓存标记已存在,就直接取走过期的缓存。

3、二级缓存

缓存两份数据,一份设置过期时间,另一份设置永不过期作为二级缓存。优先查缓存,查不到缓存,就查二级缓存,并加上redis标记去更新缓存,其他线程检查到redis更新缓存标记已存在,就直接取走二级缓存。

还有2个要注意的点:

1、在上述逻辑过期二级缓存方法中, 更新缓存这个动作可以写个异步任务去完成。

2、在上述逻辑过期二级缓存方法中,为了解决第一次查缓存就没有数据导致高并发穿过缓存的情况,需要在上线前就准备好缓存数据(比如在django的migrate中或者celery的@worker_ready.connect信号中更新缓存)。

3、其实还有一种办法也可以解决项目中的问题,就是设置一个定时任务去缓存全量数据,但是我觉得太臃肿,太依赖celery

标签:缓存,过期,击穿,redis,接口,二级缓存,更新,解决
来源: https://www.cnblogs.com/libaiyun/p/16477367.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有