缓存雪崩、击穿、穿透

目录

前言

一、缓存雪崩

1.大量数据同时过期

1.均匀设置过期时间

2.互斥锁

3.后台更新缓存

2.Redis故障宕机

1.服务熔断或请求限流机制

2.构建Redis缓存高可靠集群

二、缓存击穿

1.设置互斥锁;

2.不给热点数据设置过期时间,由后台更新缓存。

三、缓存穿透

1.非法请求的限制

2.缓存空值或者默认值

3.使用布隆过滤器快速判断数据是否存在,避免通过查询数据库来判断数据是否存在

布隆过滤器

总结


前言

用户的数据一般存在数据库,也就是磁盘里。

如果用户请求全访问数据库的话,数据库很容易崩溃,一般在他们中间回家一个Redis作为缓存层。(Redis是内存数据库,相当于数据缓存在内存里面,内存的读写速度比硬盘快好几个数量级,系统性能大大提升)

当缓存层出现异常的时候就可能遇到三个问题:

缓存雪崩、缓存击穿、缓存穿透。

一、缓存雪崩

有两种情况会出现缓存雪崩:

1.大量缓存数据同时过期

2.Redis故障

为了保证缓存中的数据和数据库中的数据一致性,会给Redis里的数据设置过期时间,当缓存数据过期后,用户访问的数据如果不在缓存里,业务系统需要重新生成缓存,因此就会访问数据库,并将数据更新到Redis里面,这样后续请求都可以直接命中缓存。

但是,当大量缓存数据在用一时间过期或者Redis故障宕机时,如果此时有大量的用户请求,都无法在Redis中处理,于是又全部都直接访问数据库,从而导致数据库的压力骤增,严重的会造成数据库宕机,可能造成整个系统崩溃,这就是缓存雪崩

1.大量数据同时过期

大量数据同事过期导致的缓存雪崩可以:均匀设置过期时间,互斥锁,后台更新缓存。

1.均匀设置过期时间

在缓存数据设置过期时间时,给这些数据的过期时间随机加上一个随机数,保证他们不会在同一时间过期。

2.互斥锁

在用户访问时加互斥锁,当用户访问的数据不在Redis里,加上互斥锁,保证同一时间内只有一个请求来构建缓存 (从数据库读取数据,再将数据更新到Redis里),当缓存构建完成后,再释放锁。如果有请求未能获取互斥锁,要么等待所释放后重新读取缓存,要么就返回空值或者默认值。

实现互斥锁的时候要设置超时时间,不然第一个请求拿到了锁,然后这个请求发生了某种意外而一直阻塞,一直不释放锁,这个时候其他请求也一直拿不到锁,整个系统就会出现无响应的现象。

3.后台更新缓存

缓存不设置有限期,而是让缓存永久有效,将更新缓存的工作交由后台线程定时更新。

这里也有一个问题。缓存不设置有效期并不是意味着数据能一直在内存里,因为当系统内存紧张的时候,有些缓存数据会被淘汰,而在缓存被淘汰到下一次后台定时更新缓存的这段时间内,业务线程读取缓存失败就返回空值,业务的视角就以为是数据丢失。

针对于业务视角的数据丢失问题,有两种解决方式。

1.后台线程不仅负责定时更新缓存,而且也负责频繁地检测缓存是否有效,如果检测到缓存失效了,马上从数据库中读取数据,并更新到缓存。(这个解决方式的检测时间间隔不能太长,太长也就导致用户获取的数据是一个空值而不是真正的数据,所以检测的间隔时间最好是毫秒级,但是总归是有个间隔时间,用户体验一般)

2.第二种方式就会好很多,因为它在业务线程发现缓存数据失效后,才通过消息队列发送一条消息通知后台线程更新缓存,后台线程收到消息后也要先去检测缓存是否存在,不存在才读取数据库数据,并将数据加载到缓存。(这方式的更新会更及时,用户体验提高)

缓存预热:在业务刚上线的时候,最好是提前把数据缓存起来,而不是等待用户访问才来触发缓存构建,就是缓存预热,后台更新缓存的机制刚好也适合干这个事情。

2.Redis故障宕机

常见的应对方式:服务熔断或者请求限流机制;构建Redis缓存高可靠集群。

1.服务熔断或请求限流机制

服务熔断机制:暂停业务应用对缓存服务的访问,直接返回错误。等到Redis恢复正常后,再允许业务应用访问缓存服务。

请求限流机制:服务熔断会导致全部业务都无法正常工作,请求限流机制的话,就只将少部分请求发送到数据库进行处理,再多的请求就在入口直接拒绝服务,等到Redis恢复正常并把缓存预热完后,在解除请求限流的机制。

2.构建Redis缓存高可靠集群

之前说的服务熔断或者请求限流机制是缓存雪崩发生后的应对方案,为了避免由于Redis故障宕机导致的缓存雪崩问题,最后通过主从节点的方式构建Redis缓存高可靠集群,如果Redis缓存的主节点故障宕机,从节点可以切换成为主节点,继续提供缓存服务。

二、缓存击穿

缓存击穿可以看成缓存雪崩的一个子集。

如果缓存中的某个热点数据过期了,此时大量的请求访问了该热点数据,就无法从缓存中读取,直接访问数据库,数据库很容易就被高并发的请求冲垮了。这就是缓存击穿的问题。

解决方式可以用到前面说的:

1.设置互斥锁;

2.不给热点数据设置过期时间,由后台更新缓存

三、缓存穿透

当用户访问的数据,既不在缓存中,也不在数据库中,没办法构建缓存数据。。。

当有大量这样的请求来到时,数据库的压力骤增。

一般由两种情况导致:业务误操作,导致缓存中的数据和数据库中的数据都被错误删除了,所以缓存和数据库中都没有数据;黑客恶意攻击,故意大量访问某些不存在数据的业务。

应对方案:非法请求的限制;缓存空值或者默认值;使用布隆过滤器快速判断数据是否存在,避免通过查询数据库来判断数据是否存在。

1.非法请求的限制

在API入口处判断请求参数是否合理,比如请求参数是否含有非法制、请求字段是否存在,如果判断出是恶意请求就直接返回错误,避免进一步访问缓存和数据库。

2.缓存空值或者默认值

当线上业务发现缓存穿透的现象时,可以针对查询的数据,在缓存中设置一个空值或者默认值,这样后续请求就可以从缓存中读取到空值或者默认值,返回给应用,而不会继续查询数据库。

3.使用布隆过滤器快速判断数据是否存在,避免通过查询数据库来判断数据是否存在

在写入数据库数据时,使用布隆过滤器做一个标记,然后在用户请求到来时,业务线程确认缓存失效后,可以通过查询布隆过滤器快速判断数据是否存在,如果不存在,就不用通过查询数据库来判断数据是否存在。

即使发生了缓存穿透,大量请求只会查询Redis和布隆过滤器,而不会查询数据库,保证了数据库能正常运行,Redis自身也是支持布隆过滤器的。

布隆过滤器

布隆过滤器有初始值都是0的位图数组和N个哈希函数两部分组成。当写入数据库数据时,在布隆过滤器里做个标记,这样下次查询数据是否在数据库时,就只要查询布隆过滤器,如果查询到数据没有内标记,就说明该数据就不在数据库中。

第一步,使用n个哈希函数分别对数据做哈希计算,得到n个哈希值;

第二步,将第一步得到的n个哈希值对位图数组的长度取模,得到每个哈希值在位图数组的对应位置。

第三步,将每个哈希值在位图数组的对应位置的之后设置为1。

比如,这个n可以设置为3,也就是如果一个数据存在,那么它在位图数组中有三个位置为1,查询时,只要判断这个数据对应的三个位置是不是都是1,只要有一个为0,就认为该数据不存在于数据库中。

当然,布隆过滤器会有哈希冲突的可能性,比如两个不同的数据,在相同的位置都是1,但是只存在其中一个数据时,就会存在误判的情况。

因此,查询布隆过滤器判断数据是否存在时,并不一定能证明数据库中存在这个数据,但是查询布隆过滤器不存在该数据时,那么,该数据就一定不在数据库中。

总结

过段时间我来再背一遍。 

什么是缓存雪崩、击穿、穿透? | 小林coding (xiaolincoding.com)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

可行性研究报告-范例直接套用

1业务需求可行性分析 2技术可行性分析 2.1规范化原则 2.2高度的兼容性和可移植性 2.3人性化、适用性 2.4标准化统一设计原则 2.5先进安全可扩展性原则 3开发周期可行性分析 4人力资源可行性分析 5成本分析 6收益分析 7结论 软件开发多套实际项目案例、方案、源码获取&#xff1…

使用API有效率地管理Dynadot域名,进行DNS域名解析

关于Dynadot Dynadot是通过ICANN认证的域名注册商,自2002年成立以来,服务于全球108个国家和地区的客户,为数以万计的客户提供简洁,优惠,安全的域名注册以及管理服务。 Dynadot平台操作教程索引(包括域名邮…

nodejs,JSDOM 补 window环境

window[atob] 是一个在浏览器中使用的 JavaScript 函数,用于将 base64 编码的字符串解码为原始数据。具体来说,atob 函数会将 base64 字符串解码为一个 DOMString,其中包含解码后的二进制数据。这在处理从服务器获取的 base64 编码的数据或在…

RedisDesktopManager连接Ubuntu的Redis失败解决办法

配置redis 1.设置redis在后台服务,修改配置文件 默认情况下是 no ,修改为yes,可以后台服务 2、设置redis端口,默认端口是6379,可以根据自己的需要,找到/et/redis/redis.conf文件, 修改port 3、设置密码 配置文件中…

基于pytorch的手写体识别

一、环境搭建 链接: python与深度学习——基础环境搭建 二、数据集准备 本次实验用的是MINIST数据集,利用MINIST数据集进行卷积神经网络的学习,就类似于学习单片机的点灯实验,学习一门机器语言输出hello world。MINIST数据集,可以…

【书籍推广】这本书太好了!150页就能让你上手大模型应用开发

文章目录 蛇尾书特色蛇尾书思维导图作译者简介业内专家书评 如果问个问题:有哪些产品曾经创造了伟大的奇迹?ChatGPT 应该会当之无愧入选。仅仅发布 5 天,ChatGPT 就吸引了 100 万用户——当然,数据不是关键,关键是其背…

【Unity】VR开发的正确测试节奏

【背景】 VR开发由于其测试时对设备的依赖较大,因此有时在没有测试条件时想当然地写了大量代码,一旦到正式测试时需要debug,往往无法判断到底是哪个环节的问题(代码,环境,等等)。相对于PC平台的…

AI预测福彩3D第2弹【2024年3月5日预测】

书接上回,首先声明下,写这一系列文章的目的不为别的,就是想看下到底使用一些强大的AI算法能不能挖掘出彩票的规律,毕竟彩票的规律太乱,不是说没有规律,而是规律太多。经过上一篇文章的图片,大家…

git使用教程14-Pycharm版本控制与分支管理

一、版本控制 1、版本控制介绍 (1)Version Control System 版本控制系统,简称VCS。 (2)版本控制系统分类: 集中式版本控制工具:SVN 分布式版本控制工具:Git 2、Pycharm 支持的版本…

C++:Vector的使用

一、vector的介绍 vector的文档介绍 1. vector是表示可变大小数组的序列容器。 2. 就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问,和数组一样高效。但是又不像数组,它的大小是可以…

全链路监控

1. 全链路监控的兴起与发展 当代的互联网的服务,通常都是用复杂的、大规模分布式集群来实现的。互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发、可能使用不同的编程语言来实现、有可能布在了几千台服务器&…

CentOS 7操作系统安装教程

CentOS 7操作系统安装教程 CentOS 7是一款功能强大、稳定可靠的操作系统,适用于服务器、桌面等多种场景。下面将介绍CentOS 7的安装教程。 准备工作 下载CentOS 7镜像文件:https://mirrors.tuna.tsinghua.edu.cn/centos/7/isos/x86_64/准备安装介质&am…

【新书推荐】13.2 应用举例

本节内容:磁盘文件管理功能号调用应用举例。 ■例1:显示文本文件内容t13-1.asm。 ■例2:将键盘输入字符存入文件t13-2.asm。 ■例3:文件拼接t13-3.asm。 13.2.1 例1:显示文本文件内容 动手实验93:写一个…

Centos 9 安装 k8s

为了尽可能契合生产环境的部署情况,这里用kubeadm安装集群,同时方便跟随笔记一步步实践的过程,也更加了解k8s的一些特性和基础知识。 先决条件 这里将通过虚拟机安装3台centos stream 9服务器,并组成kubeneters集群(…

如何在MinIO系统中进行配置并结合内网穿透实现公网远程连接上传文件

文章目录 前言1. 创建Buckets和Access Keys2. Linux 安装Cpolar3. 创建连接MinIO服务公网地址4. 远程调用MinIO服务小结5. 固定连接TCP公网地址6. 固定地址连接测试 前言 MinIO是一款高性能、分布式的对象存储系统,它可以100%的运行在标准硬件上,即X86等…

ROS2中std_msgs/msg/Header 数据含义及使用

ROS2中std_msgs/msg/Headerr 数据含义及使用 ROS官方消息说明数据说明使用ros2标准的Header案例代码解释测试结果 ROS官方消息说明 ROS2中std_msgs消息包含类型 https://docs.ros2.org/latest/api/std_msgs/msg/std_msgs/msg/Header Message std_msgs/msg/Header数据格式&…

“零碳未来”:引领全球向低碳经济转型

全球环境基金(GEF),这个由183个国家和地区组成的国际合作组织,是世界银行1990年创建的实验项目,一直致力于支持环境友好型项目,推动全球环境改善。而“零碳未来”不仅是一个由全球环境基金(GEF)创建的跨越国界的全新交易平台,更是一个致力于推动全球向低碳经济转型的零碳排放生…

ChromeDriver全版本下载教程

确定自己的Chrome版本 step1. 打开Chrome浏览器右上角的三个点,再点击设置 step2. 在设置中点击“关于Chrome”,圈起来的红框即为当前Chrome版本,我的版本就是121.0.6167.185 在json中查找自己对应ChromeDriver版本下载链接 一般教程会让你…

2_SQL

文章目录 SQL数据完整性实体完整性域完整性参照完整性default(默认值)comment(注释) 多表设计一对一一对多多对多数据库三大范式第一范式:原子性第二范式:唯一性第三范式:数据的冗余 多表查询连…

【问题】解决c++调用exosip是报错,无法解析的外部符号 _DnsQueryConfig@24

问题描述: error LNK2019: 无法解析的外部符号 _DnsQueryConfig24,函数 _eXosip_dnsutils_naptr 中引用了该符号 DnsQueryConfig是windowAPI,可查阅msdn。 #pragma comment(lib,"ws2_32.lib") #pragma comment(lib,"Dnsapi.…