如何理解Redis中的缓存雪崩,缓存穿透,缓存击穿?

目录

一、缓存雪崩

1.1 解决缓存雪崩问题

二、缓存穿透

2.1 解决缓存穿透

三、缓存击穿

3.1 解决缓存击穿

3.2 如何保证数据一致性问题?


一、缓存雪崩

缓存雪崩是指短时间内,有大量缓存同时过期,导致大量的请求直接查询数据库,从而对数据库造成了巨大的压力,严重情况下可能会导致数据库宕机的情况叫做缓存雪崩。

我们先来看下正常情况下和缓存雪崩时程序的执行流程图,正常情况下系统的执行流程如下图所示:

 缓存雪崩的执行流程如下:

从以上图片我们可以发现,1导致缓存雪崩的主要原因有以下三个:

  1. 缓存过期时间设置不合理 :由于大量缓存数据设置的过期时间相同,导致在某一时刻缓存大量失效,这样就使大量请求直接打到数据库上。
  2. 提供缓存的服务器发生障碍:缓存的服务器出现故障,无法提供缓存服务,那么所有请求就会直接访问数据库。
  3. 缓存数据的热点分布不均:由于是大量缓存直击数据库,所以可能是热点数据分布不均匀,都集中到某个缓存节点上,当这些节点发生故障或者数据失效的时候,会导致请求直接打到数据库。

1.1 解决缓存雪崩问题

 ① 随机生成缓存过期时间

可以避免缓存同时过期

package org.example;import redis.clients.jedis.Jedis;import java.util.Random;public class Main {public static void main(String[] args) {// 连接到本地 Redis 服务Jedis jedis = new Jedis("localhost", 6379);//缓存原来的失效时间int exTime = 10 * 60;//随机数生成Random randow = new Random();jedis.setex("myKey", exTime+ randow.nextInt(1000), "Hello, Redis!");// 关闭连接jedis.close();}
}

使用多级缓存(成本高,但是也较为主流)

二级缓存指的是除了Redis缓存之外,再设计一个二级缓存,这个二级缓存的过期时间比Redsi中要大一点,当Redis是失效后,先查二级缓存,如果查到数据了,就会直接从二级缓存拿数据返回给前端。不会走数据库,毕竟数据库的资源很宝贵。

这里的本地缓存:可以是mybatis的二级缓存(后两者更为主流,因为mybatis的二级缓存可以存的东西太少了),或者是Google的Guava Cache,Caffeine等。

但是设计二级缓存需要多写很多代码,而且会增加系统的复杂性。虽然查询的时候,走二级缓存没有问题,但是应用程序执行写入操作的时候,那么原本只需要保证Redis里的数据库和数据库里的数据一致即可,但是现在还要保证二级缓存的一致性,数据的一致性更难保证了。

但是Caffeine有方案可以保证本地缓存一致性的问题。

③ 缓存过期前预加载:

在缓存即将过期之前,提前异步加载缓存,避免在缓存失效时大量请求直接打到数据库或者后端服务。

例如看门狗机制,但是实现起来并不简单,因为还需要设置定时任务之类,但是定时任务也有可能会挂,并且也是有一定开销。

④ 开启限流或降级功能:

当缓存发生雪崩时,采用限流或降级的机制来减少服务器的压力,保证系统的可用性。

⑤ 实时监控和预警:

通过监控缓存的状态和命中率,及时发现缓存问题,预警系统管理员或运维人员。

二、缓存穿透

缓存穿透是指查询数据库和缓存都无数据,因为数据库查询无数据,出于容错考虑,不会将结果保存到缓存中,因此每次请求都会去查询数据库,从而给数据库带来了额外的压力,降低了系统性能的情况就叫做缓存穿透。

也就是说缓存穿透是因为数据库查询无数据,出于容错考虑,不会将结果保存到缓存中,因此每次请求都会去查询数据库,这种情况就叫做缓存穿透。

缓存穿透 执行流程如下图所示:

缓存穿透执行流程:Redis 数据库 都被穿透。

2.1 解决缓存穿透

缓存穿透的常见解决方案有以下几个:

1.缓存空对象: 对于查询结果为 nul 或不存在的数据,也可以将它们以特殊值(如"NULL"、特定标识符)进行缓存,并设置较短的过期时间。这样,短时间内相同的查询请求就可以直接从缓存中获得响应,避免了对数据库的直接查询。

2. 布隆过滤器(Bloom Filter): 在请求到达缓存之前,先通过布降过滤器判断数据可能存在还是一定不存在。对于确定不存在的数据,可以直接返回;可能存在则继续査询缓存和数据库。布隆过滤器是一种空间效率极高的概率型数据结构,它会给出“可能存在“或“肯定不存在”的答案。

3. 开启限流功能:当发现大量连接未命中的请求时,可以采用限流策略限制同一时间段内向数据库发送的查询请求数量,减轻数据库压力。

2.2 什么是布隆过滤器? 

布隆过滤器是一种空间效率极高的概率性数据结构,可以用于判断一个元素是否在一个集合中。

它基于位数组和多个哈希函数的原理,可以高效地进行元素的查询,并且占用的空间相对较小,

如下图所示:

这里面存的就是比特,即0或1。根据 key 值计算出它的存储位置,然后将此位置标识全部标识为 1(未存放数据的位置全部为 0),查询时也是查询对应的位置是否全部为 1,如果全部为 1,则说明数据是可能存在的,否则一定不存在.

这种采用存储三个比特的方法,可以有效避免hash冲突,因为如果只存储一个的话,hash冲突可能发生比较频繁。

也就是说,如果布隆过滤器说一个元素不在集合中,那么它一定不在这个集合中;但如果它说一个元素在集合中则有可能是不存在的(存在误差)。 

执行过程

布隆过滤器的具体执行步骤如下:

  1. 在 Redis 中创建一个位数组,用于存储布降过滤器的位向量,每个位置的值设置为 0.
  2. 添加元素到布隆过滤器时,对元素进行多次哈希计算,并将对应的位数组位置设置为 1。
  3. 查询元素是否存在时,对元素进行多次哈希计算,并检查对应的位数组位置是否都为 1,都为1 表示可能存在,其中有一个为 0则一定不存在。

使用场景

布隆过滤器的主要使用场景有以下几个:

  1. 大数据量去重:可以用布降过滤器来进行数据去重,判断一个数据是否已经存在,避免重复插入。
  2. 防止缓存穿透:可以用布隆过滤器来过滤掉恶意请求或请求不存在的数据,避免对后端存储的频繁访问。
  3. 网络爬虫 URL 去重:可以用布降过滤器来判断 URL 是否已经被爬取,避免重复爬取。

三、缓存击穿

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

主要原因是: 热点数据再缓存中失效或淘汰,并发请求同时访问该数据库,导致缓存无法命中。

缓存击穿的执行流程:(Redis 被击穿)

3.1 解决缓存击穿

① 设置永不过期:

对于某些热点缓存,我们可以设置永不过期,这样就能保证缓存的稳定性,但需要注意在数据更改之后,要及时更新此热点缓存,不然就会造成查询结果的误差。

② 缓存过期前预加载

在缓存即将过期之前,提前异步加载缓存,避免在缓存失效时大量请求直接打到数据库或者后端服务。

例如看门狗机制,但是实现起来并不简单,因为还需要设置定时任务之类,但是定时任务也有可能会挂,并且也是有一定开销。

③ 使用多级缓存:

可以使用多级缓存架构,将热门数据同时缓存在多个缓存节点上,避免单一节点故障导致请求直接访问数据库或者后端服务,例如可以设计多级缓存,也就是使用分布式缓存(Redis)+本地缓存(Caffeine/Guava Cache),如下图所示:

但是设计二级缓存需要多写很多代码,而且会增加系统的复杂性。虽然查询的时候,走二级缓存没有问题,但是应用程序执行写入操作的时候,那么原本只需要保证Redis里的数据库和数据库里的数据一致即可,但是现在还要保证二级缓存的一致性,数据的一致性更难保证了。

但是Caffeine有方案可以保证本地缓存一致性的问题。

④ 开启限流或降级功能:

当缓存发送雪崩时,采用限流或降级的机制来减少服务器的压力,保证系统的可用性。

3.2 如何保证数据一致性问题?

如何保证本地缓存的一致性?
在分布式系统中,使用本地缓存最大的问题就是一致性问题,所谓的一致性问题指的是当数据库发生数据变更时缓存也要跟着一起变更。而分布式系统中每台机器都有自己的本地缓存,所以想要保证(本地缓存的)一致性是个比较难的问题,但通过以下手段可以最大程度的保证本地缓存的一致性问题:

  1. 本地缓存失效时间尽量短,短的存活周期,保证了尽可能的保证了一致性。
  2. 通过微服务中的配置中心(例如 Nacos)来协调,因为所有服务器都连接的配置中心,所以当数据修改之后可以给配置中心推送一个配置修改的信息,然后配置中心再把变更信息推送给各个服务,服务订阅到配置变更消息之后,就会更新自己的本地缓存,这样就实现了数据的一致性。
  3. 使用缓存框架的自动更新功能,例如 Caffeine 中的 refresh 功能自动刷新缓存。

不同的业务系统,会采用不同的解决方案,例如以下这些场景和对应的解决方案:

  • 如果对数据一致性要求不是很高,并且程序的并发压力不大的情况下,可能使用方案 1,也就是设置本地缓存短时间内失效的解决方案,因为它的实现最简单。
  • 如果对数据的一致性要求极高,且有配置中心的情况下,可使用配置中心协调和同步本地缓存。
  • 相反,如果对一致性要求没有那么高,且为高并发的系统,那么可以采用本地缓存的自动更新功能来实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/518302.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VS2022打包C#安装包(最新、最全)

开发c#的一个小工具到打包环境碰壁了,在网上找了很多资料耶踩了很多坑,耗时1hour才打包完毕,避免以后碰到类似的问题再次记录,自认为步骤比较全面,如果有帮助麻烦点个赞呗!!! 一、Mi…

【异常处理】BadSqlGrammarException低级SQL语法异常

报错 org.springframework.jdbc.BadSqlGrammarException: ### Error querying database. Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use …

极狐GitLab 如何设置 Markdown 中的图片大小

GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署极狐GitLab。 使用极狐GitLab 进行代码托管或者 CI/CD,都避免不了…

奔跑不息的鞋履行业再迎分化,百丽时尚逆势而上?

新事物的诞生带来新生机的同时,从来也都是伴有腥风血雨的。 就如,互联网电商之于服装鞋履新零售。 据悉,近日鞋履业头部之一的千百度在历经多次转型失败后,最终还是走上了“老大哥”百丽时尚的老路——退市进行私有化转型。此外…

java基础-锁之volatilesynchronized

文章目录 volatilevolatile内存语义volatile的可见性volatile无法保证原子性volatile禁止重排优化硬件层的内存屏障volatile内存语义的实现下面是基于保守策略的JMM内存屏障插入策略。下面是保守策略下,volatile写插入内存屏障后生成的指令序列示意图下图是在保守策…

阿里云2核2G服务器61元和99元性能测评

阿里云2核2G服务器多少钱?99元一年,轻量云服务器是61元一年。2核2G服务器性能如何?性能很不错,不限制CPU性能,99元2核2G服务器是ECS经济型e实例,61元2核2G服务器是轻量应用服务器,都是3M公网带宽…

数据结构与算法-归并排序

引言 在计算机科学的广阔领域中,数据结构与算法犹如两大基石,支撑着软件系统高效运行。本文将深度剖析一种基于分治策略的排序算法——归并排序,并探讨其原理、实现步骤以及优缺点,以期帮助读者深入理解这一高效的排序方法。 一、…

想打造爆款AI应用?ai虚拟数字人制作助你一臂之力

如今,随着人工智能技术的飞速发展,AI应用已经渗透到我们生活的方方面面。而在这个充满竞争和创新的时代,不少企业都在努力寻找打造爆款AI应用的机会。其中,AI虚拟数字人制作可以为他们提供一臂之力。 AI虚拟数字人制作是指利用人…

如何制作聊天机器人:人工智能驱动的世界中开发人员的注意事项

作者:来自 Elastic Aditya Tripathi 世界每天都越来越受到人工智能的推动。 事实上,你很难找到尚未宣布将人工智能以某种方式集成到其技术堆栈中的科技公司。 愤世嫉俗者可能会说这是一个过渡阶段,但人工智能如此受欢迎的原因是它是一组多功能…

Docker本地部署Redis容器结合内网穿透实现无公网ip远程连接

文章目录 前言1. 安装Docker步骤2. 使用docker拉取redis镜像3. 启动redis容器4. 本地连接测试4.1 安装redis图形化界面工具4.2 使用RDM连接测试 5. 公网远程访问本地redis5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定TCP地址远程访问 前言 本文主要介绍如何在Ub…

护眼台灯哪个品牌最好?2024五款主流台灯实测推荐!

对很多家长来说,孩子的健康比什么都重要。不过现在的儿童青少年近视率却非常高,正因为如此护眼台灯就一直是家长十分关注的灯具。可如今市场中却存在很多劣质产品,忽视产品做工以及选材用料等问题,导致照明体验感差、使用不方便&a…

【YOLO系列】YOLOv9论文超详细解读(翻译 +学习笔记)

前言 时隔一年,YOLOv8还没捂热,YOLO系列最新版本——YOLOv9 终于闪亮登场! YOLOv9的一作和v7一样。v4也有他。 他于2017年获得台湾省National Central University计算机科学与信息工程博士学位,现在就职于该省Academia Sinica的…