详解缓存穿透、缓存雪崩、缓存击穿

article/2025/8/26 2:18:00

背景

在现代软件架构中,缓存的应用已经非常普及。缓存的使用在面试和实践中都是避不开的硬技能、硬知识,如果你说还不太熟悉缓存的使用,可能都不好意思说自己是程序员。

这篇文章,带大家进一步学习在缓存使用中不得不考虑三个特殊场景:缓存穿透、缓存雪崩、缓存击穿。

为什么说不得不考虑?因为如果不考虑这些特殊的场景,在高并发的情况可能直接导致系统崩溃。下面以常见的Redis缓存组件为例来讲解这三种场景及解决方案。

大前提

当我们使用缓存时,目标通常有两个:第一,提升响应效率和并发量;第二,减轻数据库的压力。

而本文中所提到的这三种场景:缓存穿透、缓存雪崩和缓存击穿的发生,都是因为在某些特殊情况下,缓存失去了预期的功能所致。

当缓存失效或没有抵挡住流量,流量直接涌入到数据库,在高并发的情况下,可能直接击垮数据库,导致整个系统崩溃。

这就是我们需要知道的大前提,而缓存穿透、缓存雪崩和缓存击穿,只不过是在这个大前提下的不同场景的细分场景而已。

缓存穿透

大多数情况,缓存可以减少数据库的查询,提升系统性能。

通常流程是:一个请求过来,先查询是否在缓存当中,如果缓存中存在,则直接返回。如果缓存中不存在对应的数据,则检索数据库,如果数据库中存在对应的数据,则更新缓存并返回结果。如果数据库中也不存在对应的数据,则返回空或错误。

缓存穿透(cache penetration)是用户访问的数据既不在缓存当中,也不在数据库中。出于容错的考虑,如果从底层数据库查询不到数据,则不写入缓存。这就导致每次请求都会到底层数据库进行查询,缓存也失去了意义。当高并发或有人利用不存在的Key频繁攻击时,数据库的压力骤增,甚至崩溃,这就是缓存穿透问题。

缓存穿透

缓存穿透发生的场景一般有两类:

  • 原来数据是存在的,但由于某些原因(误删除、主动清理等)在缓存和数据库层面被删除了,但前端或前置的应用程序依旧保有这些数据;

  • 恶意攻击行为,利用不存在的Key或者恶意尝试导致产生大量不存在的业务数据请求。

缓存穿透通常有四种解决方案,我们逐一介绍分析。

方案一:缓存空值(null)或默认值

分析业务请求,如果是正常业务请求时发生缓存穿透现象,可针对相应的业务数据,在数据库查询不存在时,将其缓存为空值(null)或默认值。需要注意的是,针对空值的缓存失效时间不宜过长,一般设置为5分钟之内。当数据库被写入或更新该key的新数据时,缓存必须同时被刷新,避免数据不一致。

方案二:业务逻辑前置校验

在业务请求的入口处进行数据合法性校验,检查请求参数是否合理、是否包含非法值、是否恶意请求等,提前有效阻断非法请求。比如,根据年龄查询时,请求的年龄为-10岁,这显然是不合法的请求参数,直接在参数校验时进行判断返回。

方案三:使用布隆过滤器请求白名单

在写入数据时,使用布隆过滤器进行标记(相当于设置白名单),业务请求发现缓存中无对应数据时,可先通过查询布隆过滤器判断数据是否在白名单内,如果不在白名单内,则直接返回空或失败。

方案四:用户黑名单限制

当发生异常情况时,实时监控访问的对象和数据,分析用户行为,针对故意请求、爬虫或攻击者,进行特定用户的限制;

当然,可能针对缓存穿透的情况,也有可能是其他的原因引起,可以针对具体情况,采用对应的措施。

缓存雪崩

在使用缓存时,通常会对缓存设置过期时间,一方面目的是保持缓存与数据库数据的一致性,另一方面是减少冷缓存占用过多的内存空间。

但当缓存中大量热点缓存采用了相同的实效时间,就会导致缓存在某一个时刻同时实效,请求全部转发到数据库,从而导致数据库压力骤增,甚至宕机。从而形成一系列的连锁反应,造成系统崩溃等情况,这就是缓存雪崩(Cache Avalanche)。

缓存雪崩

上面讲到的是热点key同时失效的场景,另外就是由于某些原因导致缓存服务宕机、挂掉或不响应,也同样会导致流量直接转移到数据库。

所以,缓存雪崩的场景通常有两个:

  • 大量热点key同时过期;

  • 缓存服务故障;

缓存雪崩的解决方案:

  • 通常的解决方案是将key的过期时间后面加上一个随机数(比如随机1-5分钟),让key均匀的失效。

  • 考虑用队列或者锁的方式,保证缓存单线程写,但这种方案可能会影响并发量。

  • 热点数据可以考虑不失效,后台异步更新缓存,适用于不严格要求缓存一致性的场景。

  • 双key策略,主key设置过期时间,备key不设置过期时间,当主key失效时,直接返回备key值。

  • 构建缓存高可用集群(针对缓存服务故障情况)。

  • 当缓存雪崩发生时,服务熔断、限流、降级等措施保障。

缓存击穿

缓存雪崩是指只大量热点key同时失效的情况,如果是单个热点key,在不停的扛着大并发,在这个key失效的瞬间,持续的大并发请求就会击破缓存,直接请求到数据库,好像蛮力击穿一样。这种情况就是缓存击穿(Cache Breakdown)。

缓存击穿

从定义上可以看出,缓存击穿和缓存雪崩很类似,只不过是缓存击穿是一个热点key失效,而缓存雪崩是大量热点key失效。因此,可以将缓存击穿看作是缓存雪崩的一个子集。

缓存击穿的解决方案:

  • 使用互斥锁(Mutex Key),只让一个线程构建缓存,其他线程等待构建缓存执行完毕,重新从缓存中获取数据。单机通过synchronized或lock来处理,分布式环境采用分布式锁。

  • 热点数据不设置过期时间,后台异步更新缓存,适用于不严格要求缓存一致性的场景。

  • ”提前“使用互斥锁(Mutex Key):在value内部设置一个比缓存(Redis)过期时间短的过期时间标识,当异步线程发现该值快过期时,马上延长内置的这个时间,并重新从数据库加载数据,设置到缓存中去。

小结

本文介绍了在使用缓存时经常会遇到的三种异常情况:缓存穿透、缓存雪崩和缓存击穿。

三种异常情况从根本上来说都是因为本应该访问缓存的,但是缓存不存在或服务异常,导致流量直接进入了数据库层面。

其中缓存雪崩和缓存击穿是因为数据不存在(或服务异常获取不到),导致大量请求访问数据库,从而导致数据库压力骤增,甚至崩溃。

而缓存穿透则是由于数据本身就不存在,导致缓存没有进行数据缓存,流量进入数据库层。

针对不同的缓存异常场景,可选择不同的方案来进行处理。当然,除了上述方案,我们还可以限流、降级、熔断等服务层的措施,也可以考虑数据库层是否可以进行横向扩展,当缓存异常发生时,确保数据库能够抗住流量,不至于让整个系统崩溃。


http://chatgpt.dhexx.cn/article/o7JQ7XWL.shtml

相关文章

【Redis】缓存击穿问题及其解决方案

【Redis】缓存击穿问题及其解决方案 文章目录 【Redis】缓存击穿问题及其解决方案1. 缓存击穿概念2. 解决方案2.1 互斥锁2.1.1 互斥锁的优缺点2.1.2 互斥锁的代码实现 2.2 逻辑过期2.2.1 逻辑过期的优缺点2.2.2 逻辑过期的代码实现 1. 缓存击穿概念 缓存击穿:缓存击…

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

文章目录 一、缓存穿透1. 概念2. 解决方案 二、缓存击穿1. 概念2. 解决方案 三、缓存雪崩1. 概念2. 解决方案 一、缓存穿透 1. 概念 key 对应的数据在redis中并不存在,每次针对此 key的请求从缓存获取不到,请求转发到数据库,访问量大了可能…

Redis中的缓存穿透、雪崩、击穿的原因以及解决方案(详解)

一、概述 ① 缓存穿透:大量请求根本不存在的key(下文详解) ② 缓存雪崩:redis中大量key集体过期(下文详解) ③ 缓存击穿:redis中一个热点key过期(大量用户访问该热点key,…

Redis——缓存击穿、穿透、雪崩

1、缓存穿透: (1)问题描述:key对应的数据并不存在,每次请求访问key时,缓存中查找不到,请求都会直接访问到数据库中去,请求量超出数据库时,便会导致数据库崩溃。如一个用…

ping端口

1.ping端口: telnet 62.78.63.209 10105 2.如果提示telnet不是内部或外部命令… 则:右击“此电脑”–>选择“控制面板主页”,单击“程序”,如图: 3.完成。

windows下ping端口

上图的操作完成以后 进入dos控制台 输入telnet ip地址 端口号 回车 标识已ping通 ping不通是这种提示 转载于:https://www.cnblogs.com/shianliang/p/8639392.html

windows ping 端口测试

前言 项目中存在能ping通IP地址,但是打不开web应用程序,这时需要测试端口能否ping通。 解决方法 测试是否能够ping通192.168.0.1的80端口 telnet 192.168.0.1 80遇到问题 ‘telnet’ 不是内部或外部命令,也不是可运行的程序 或批处理文件。 …

Windows Server 启用或关闭ping端口

启用或关闭 ping 端口有两种方式,如下 1、通过命令行设置 打开 ping 端口 netsh firewall set icmpsetting 8关闭 ping 端口 netsh firewall set icmpsetting 8 disable2、通过高级安全 Windows 防火墙设置 打开 “高级安全 Windows 防火墙” ,在入…

windows系统ping端口及利用telnet命令Ping 端口

第一步: 第二步:打开telnet client 第三步:telnet ip 端口

Mac系统用命令打开ping端口的方法

电脑上不了网问题相信大家都有遇到过,排查网络故障问题用到ping,之前windows系统上能够轻松打开ping端。但是如果在Mac电脑该如何打开ping端口?其实打开方法并不复杂,接下来小编给大家演示Mac系统用命令打开ping端口的方法。 Mac…

linux ping 某个端口,linux 怎么ping 端口

满意答案 cysdmt 推荐于 2016.12.05 采纳率:54% 等级:8 已帮助:864人 linux命令ping用法详解 功能说明:检测主机。 语 法:ping [-dfnqrrv][-c][-i][-i][-l][-p][-s][-t][主机名称或ip地址] 补充说明:执行…

Win10系统Ping端口及利用telnet命令Ping 端口

启用 telnet 客户端组件为 Ping 端口做准备 在程序界面下,选择“打开或关闭Windows功能”,如下图所示: 在打开的对话框中,找到“Telnet客户端”并勾选。最后点击“确定”,等待几分钟,系统将会为你开启Teln…

计算机ping使用的端口,mac系统ping端口命令怎么使用

最近电脑出问题了,上不了网,想排查下电脑的问题出在哪儿就需要ping,但是该如何打开终端如何ping呢?下面就让学习啦小编教大家MAC系统ping端口命令怎么使用吧。 Mac系统ping端口命令的使用方法 方法一: 在桌面上的DOCK栏中&#x…

w7系统怎么ping服务器,win7系统中如何ping端口命令

正常情况下,win7系统时无法ping端口的,不过要是开启了Telnrt客户端,则可以实现这一功能,启用Telnrt客户端需要用户进入Windows 组件中勾选,当然,如果用户有一个可以专门Ping端口的第三方软件也是可以的。 一…

Win10如何ping端口是否开放

如何ping端口是否开放 前言一、打开Telent Client功能1.打开控制面板2.进入启用Windows功能页面,勾选Telnet客户端3.打开cmd,输入命令 telnet ip 端口4.回车如果进入黑屏页面,则ping通了,否则显示连接失败 前言 ping具体的网址是…

自制python版 在线ping 端口检查工具 python3.5 +docker

自己有几十台服务器需要实现在线检查是否在线和网络延时情况 1.开搞。 docker run -d -p 8000:8000 -i -t -v /pyFile:/usr/src/python python:3.5 /bin/bash 在docker 部署python3.5https://blog.csdn.net/qq_44741568/article/details/120035609 2. 进入容器 &#xff0c…

ping端口的方法 - win下

方法 默认的cmd > ping xx.xx.xx.xx 是无法带端口测试的,需要工具tcping.exe帮忙下载tcping.exe,存放到任意位置,例如D:\tcping小程序下载-tcping工具(tcping.exe)免费版 - 极光下载站tcping工具可以为用户检测非常多的网络问题&#xff…

ping端口神器psping

简介 测试服务端端口是否正常,通过ping命令不能测试端口是否打开、是否可正常连通。当然Telnet也可以解决。本文分享的工具是sysInternals工具集下的一个小工具psPing,这个工具支持Ping:ICMP、TCPorUDP,以及延迟分析和带宽测试。 …

计算机ping使用的端口,Win7系统中如何Ping端口?Ping端口命令的用法

Win7系统中如何Ping端口?正常情况下,Win7系统是无法Ping端口的,不过如果启用了Telnrt客户端,则可以实现这一功能,启用Telnrt客户端需要用户进入Windows 组件中勾选,当然,如果用户有一个可以专门…

计算机ping使用的端口,Windows7系统中怎么Ping端口?利用telnet命令Ping 端口的方法...

通常,Win7系统是无法Ping端口的,不过如果你要开启了telnet客户端即可实现ping端口的功能。Windows7系统中怎么Ping端口?下面装机之家小编教你利用telnet命令Ping 端口的方法。 Windows7系统中怎么Ping端口? 一、启用 telnet 客户端…