一、缓存雪崩
缓存雪崩我们可以简单的理解为:由于原有缓存失效,新缓存未到期间(例如:我们设置缓存时采用了相同的过期时间,在同一时刻出现大面积的缓存过期),所有原本应该访问缓存的请求都去查询数据库了,而对数据库CPU和内存造成巨大压力,严重的会造成数据库宕机。从而形成一系列连锁反应,造成整个系统崩溃。
缓存正常从Redis中获取,示意图如下:
缓存失效瞬间示意图如下:
缓存雪崩的解决方案:
(1)碰到这种情况,一般并发量不是特别多的时候,使用最多的解决方案是加锁排队,伪代码如下:
加锁排队只是为了减轻数据库的压力,并没有提高系统吞吐量。假设在高并发下,缓存重建期间key是锁着的,这是过来1000个请求999个都在阻塞的。同样会导致用户等待超时,这是个治标不治本的方法!
注意:加锁排队的解决方式分布式环境的并发问题,有可能还要解决分布式锁的问题;线程还会被阻塞,用户体验很差!因此,在真正的高并发场景下很少使用!
(2)给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存,实例伪代码如下:
解释说明:
1、缓存标记:记录缓存数据是否过期,如果过期会触发通知另外的线程在后台去更新实际key的缓存;
2、缓存数据:它的过期时间比缓存标记的时间延长1倍,例:标记缓存时间30分钟,数据缓存设置为60分钟。 这样,当缓存标记key过期后,实际缓存还能把旧数据返回给调用端,直到另外的线程在后台更新完成后,才会返回新缓存。
关于缓存崩溃的解决方法,这里提出了三种方案:使用锁或队列、设置过期标志更新缓存、为key设置不同的缓存失效时间,还有一各被称为“二级缓存”的解决方法,有兴趣的读者可以自行研究。
二、缓存穿透
缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询)。这样请求就绕过缓存直接查数据库,这也是经常提的缓存命中率问题。
缓存穿透解决方案:
(1)采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。
(2)如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们仍然把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟。通过这个直接设置的默认值存放到缓存,这样第二次到缓存中获取就有值了,而不会继续访问数据库,这种办法最简单粗暴!
把空结果也给缓存起来,这样下次同样的请求就可以直接返回空了,即可以避免当查询的值为空时引起的缓存穿透。同时也可以单独设置个缓存区域存储空值,对要查询的key进行预先校验,然后再放行给后面的正常缓存处理逻辑。
三、缓存预热
缓存预热就是系统上线后,提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!
缓存预热解决方案:
(1)直接写个缓存刷新页面,上线时手工操作下;
(2)数据量不大,可以在项目启动的时候自动进行加载;
(3)定时刷新缓存;
四、缓存更新
除了缓存服务器自带的缓存失效策略之外(Redis默认的有6中策略可供选择),我们还可以根据具体的业务需求进行自定义的缓存淘汰,常见的策略有两种:
(1)定时去清理过期的缓存;
(2)当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存。
两者各有优劣,第一种的缺点是维护大量缓存的key是比较麻烦的,第二种的缺点就是每次用户请求过来都要判断缓存失效,逻辑相对比较复杂!具体用哪种方案,大家可以根据自己的应用场景来权衡。
五、缓存降级
当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。
降级的最终目的是保证核心服务可用,即使是有损的。而且有些服务是无法降级的(如加入购物车、结算)。
在进行降级之前要对系统进行梳理,看看系统是不是可以丢卒保帅;从而梳理出哪些必须誓死保护,哪些可降级;比如可以参考日志级别设置预案:
(1)一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级;
(2)警告:有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级,并发送告警;
(3)错误:比如可用率低于90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阀值,此时可以根据情况自动降级或者人工降级;
(4)严重错误:比如因为特殊原因数据错误了,此时需要紧急人工降级。
相关推荐
### Redis中的缓存雪崩与解决方案 #### 缓存雪崩定义 缓存雪崩指的是在Redis这样的缓存系统...通过对缓存雪崩、穿透、击穿等问题的有效应对,以及合理地安排缓存预热和降级策略,可以显著增强系统的健壮性和用户体验。
二、缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题 缓存雪崩是指由于原有缓存失效,新缓存未到期间,所有原本应该访问缓存的请求都去查询数据库了,而对数据库CPU和内存造成巨大压力,严重的会造成...
3、缓存问题:缓存雪崩、缓存穿透、缓存击穿、缓存预热、缓存更新、缓存降级、 4、 拓展:布隆过滤器、keys, scan、redis快原因、redis单机瓶颈、集群保证高可用、过期策略、淘汰策略、 5、 电商项目实战使用:为...
- 实施缓存预热机制,在系统启动或更新数据时,预先加载常用数据到缓存。 - 监控Redis的性能指标,如内存使用情况、QPS(每秒查询次数)等,及时发现并解决问题。 总的来说,理解和预防这些问题对于构建稳定、高效...
本文将深入探讨Redis在实际应用中遇到的三大主流问题——缓存穿透、缓存击穿和缓存雪崩,并提出相应的解决方案。 1. 缓存穿透 缓存穿透是指用户请求的数据在数据库中并不存在,导致每次请求都会直接落到数据库上,...
4. **缓存穿透、缓存雪崩与缓存击穿**: - **缓存穿透**:查询的数据既不在缓存中也不在数据库里,导致所有请求都落到数据库上。 - **缓存雪崩**:大量缓存同时失效,导致请求全部涌入数据库,造成系统崩溃。 - *...
常见的解决方法有缓存穿透、缓存雪崩和缓存击穿等问题,以及对应的解决方案,如使用布隆过滤器防止穿透,设置合理的缓存更新策略防止雪崩和击穿。 3. **分布式缓存**:当单个缓存无法满足需求时,可以采用分布式...
另外,缓存击穿、缓存雪崩和缓存穿透也是需要考虑的问题。缓存击穿是指大量请求同时命中缓存中不存在的数据,导致数据库压力增大;缓存雪崩是整个缓存系统失效,所有请求直接落到数据库上;缓存穿透则是恶意用户连续...
4. **缓存更新**:当数据源发生变化时,需要同步更新缓存,这涉及到缓存穿透、缓存雪崩和缓存击穿等问题。缓存穿透是指请求的数据既不在缓存中也不在数据库中;缓存雪崩是指大量缓存同时失效,导致所有请求都落到...
- 缓存降级:在系统负载过高或服务出现问题时,牺牲部分功能保证核心服务可用。可以通过配置开关或自动降级策略来实施。 Memcached 和 Redis 的对比: - 存储方式:Memcached 只存储在内存中,不支持持久化,而 ...
2. **缓存雪崩**:当大量缓存同时失效,请求会直接击穿到后端数据库,可能导致服务崩溃。解决办法包括设置合理的过期时间,使用互斥锁,或者结合多个缓存分担压力。 3. **缓存穿透**:恶意或异常请求导致对不存在的...
4. **缓存策略**:针对不同业务需求设置不同的缓存策略,如TTL(Time To Live),预热缓存,以及根据访问频率动态调整缓存大小等。 5. **过载保护**:设定合理的速率限制,防止恶意或异常的高访问量导致服务崩溃。...
- **缓存失效与热点更新**:缓存失效可能导致缓存穿透,热点数据更新可能引发缓存雪崩,这些都需要通过合理的缓存策略和系统架构设计来缓解。 - **缓存安全**:保护缓存数据不被未授权访问,实现数据的加密存储和...
而在资源较为紧张的环境中,缓存预热和降级处理则更为实用。 - 此外,还应该考虑到解决方案之间的兼容性和协同效应,构建多层次的防御体系,以应对不同类型的缓存击穿情况。 综上所述,缓存击穿虽然是一种普遍存在...
6. **数据预热**:在系统启动或更新数据时,可以通过Redis预先加载部分常用数据,提升系统响应速度。 四、项目实施 1. **环境搭建**:安装并配置Redis服务器,考虑单机、主从、哨兵或集群模式,根据项目规模选择...
最后,可能会讲解如何通过缓存预热、缓存更新策略等方法来优化整体性能,以及如何处理缓存雪崩、缓存穿透等问题。 在这个过程中,还会涉及其他相关技术,例如使用RabbitMQ或者Kafka作为消息队列,实现请求的异步...
5. **缓存预热**:启动时或扩展后,预先加载常用数据到缓存,减少首次请求的延迟。 6. **缓存一致性**:更新策略如Write-Through(写直达)、Write-Behind(写回),确保数据的一致性。 7. **缓存失效**:设置合理...
redis缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级.doc RPC (Remote Procedure Call)即远程过程调用.doc Spring 面试问题 TOP 50(干货推荐收藏必备).doc springboot常见面试题.doc svn和git的区别及适用场景...