什么是缓存穿透、缓存击穿、缓存雪崩,在项目中是如何解决和预防?它们分别会带来什么危害?

目录

什么是缓存穿透

影响危害

解决方案

什么是缓存击穿

影响危害

解决方案

什么是缓存雪崩

影响危害

解决方案


什么是缓存穿透

缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义,造成缓存穿透。

简单说:查询的数据既不在缓存中,也不在数据库中,从而每次查询直接打到数据库中,数据库存在多次被暴击的风险。甚至可能造成数据库崩溃。

影响危害

缓存穿透通常是由恶意用户或攻击者请求不存在于缓存和后端存储中的数据来发起的攻击,导致数据库负载过大,甚至可能使数据库崩溃。

解决方案

  • 布隆过滤器:布隆过滤器是一种空间效率很高的概率型数据结构,用于判断一个元素是否在一个集合中。将可能存在的数据哈希到一个足够大的bitmap中,不存在的数据会被拦截掉,从而避免了对底层存储系统的查询压力。

  • 空值缓存:当查询结果为空时,仍然将这个空结果进行缓存,但设置较短的过期时间。这样可以减少对后端数据库的无效查询。注意:但这会导致缓存中存储大量的空值或特殊标记,从而占用额外的内存空间。如果这类空值数据过多,会显著影响缓存的存储效率和性能。

  • 数据预校验:在请求到达缓存之前,进行数据合法性和有效性的校验,过滤掉非法或无效的请求。

什么是缓存击穿

缓存击穿通常发生在高并发访问下热点数据的缓存时间过期失效或清空后,而此时恰好有大量并发请求访问该数据,导致这些请求直接绕过缓存,大量请求同时涌入后端数据库,导致数据库负载急剧增加、甚至有可能导致系统崩溃或宕机。

影响危害

缓存击穿会导致数据库压力骤增,甚至可能引发系统崩溃,影响系统的稳定性和可用性

解决方案

  • 互斥锁:在获取数据时,使用分布式锁(如Redis的分布式锁)来控制同时只有一个请求可以去后端获取数据,其他请求需要等待锁释放。

  • 热点数据预加载:在系统启动或高峰期到来之前,将热点数据预先加载到缓存中,以减少对后端数据库的访问压力。

  • 自动刷新:为热点数据设置合理的过期时间,并启用自动刷新机制,在缓存即将过期之前,通过定时任务或后台线程提前异步加载缓存数据,确保数据在过期前被重新加载到缓存中。

什么是缓存雪崩

缓存雪崩是指在分布式系统中,缓存中的大量数据同时失效或过期,如果没有对系统进行熔断降级处理,导致大量请求直接访问数据库或后端服务,造成系统内存占用越来越多,性能急剧下降,进而引起系统崩溃。

这种现象通常会对系统造成灾难性的影响,因为它会导致后端数据库或服务承受巨大的压力或系统内存占用越来越多,可能引发服务不可用或数据丢失等问题。

雪崩和击穿、热key的问题不太⼀样的是,它是指⼤规模的缓存key同时都过期失效。

影响危害

缓存雪崩会导致数据库压力骤增,甚至可能引发系统崩溃。

解决方案

  • 随机过期时间:为不同的缓存数据设置随机的过期时间,以减少同时失效的概率。

  • 设置缓存key永不过期:设置缓存数据永不过期,避免雪崩。

  • 缓存预热:在系统启动或高峰期到来之前,将热点数据预先加载到缓存中,以减少缓存失效对后端数据库的冲击。

  • 多级缓存结合:使用多级缓存架构,如ehcache本地缓存+redis缓存等,以分散和减轻单一缓存的压力。

  • 缓存集群实现高可用:比如redis主从+哨兵模式,Redis Cluster,开启Redis持久化机制aof/rdb,尽快恢复缓存集群。

  • 服务降级:对后端数据库进行限流和降级处理,防止因缓存雪崩导致的数据库过载,如返回默认值或错误信息,以减少对后端系统的压力。

相关推荐
潇凝子潇33 分钟前
java基于ThreadLocal实现单例模式
java·开发语言·单例模式
gitax34 分钟前
连接github和ai的桥梁:GitIngest
java
数据小小爬虫41 分钟前
如何利用Java爬虫获得1688商品详情
java·开发语言·爬虫
NiNg_1_2341 小时前
IntelliJ Idea常用快捷键详解
java·ide·intellij-idea
小学鸡!1 小时前
IDEA工具使用介绍、IDEA常用设置以及如何集成Git版本控制工具
java·git·intellij-idea
添砖,加瓦1 小时前
java—网络编程TCP和UDP
java
晚安~~1 小时前
考研互学互助系统|Java|SSM|VUE| 前后端分离
java·开发语言·tomcat·maven
咕德猫宁丶1 小时前
Spring Boot + MinIO 实现分段、断点续传,让文件传输更高效
java·spring boot·后端·中间件
阿新-1 小时前
解决Spring boot集成quartz时service注入失败为null的问题
java·spring boot·后端
KaiPeng-Nie2 小时前
代码随想录day29 | leetcode 134.加油站 135.分发糖果 860.柠檬水找零 406.根据身高重建队列
java·算法·leetcode·职场和发展·贪心算法