缓存被穿透了怎么办?

文章详细阐述了缓存穿透、缓存雪崩和缓存击穿这三种现象,以及它们对数据库造成的影响。针对每种问题,文章提出了相应的解决方案,如使用空值缓存、布隆过滤器、分散过期时间、锁机制等,以提高系统的稳定性和抗压能力。

首先来了解几个概念:

缓存穿透:大量请求根本不存在的key

缓存雪崩:redis中大量key集体过期

缓存击穿:redis中一个热点key过期(大量用户访问该热点key,但是热点key过期)

穿透解决方案

    • 对空值进行缓存

    • 设置白名单

    • 使用布隆过滤器

    • 网警

雪崩解决方案

    • 进行预先的热门词汇的设置,进行key时长的调整

    • 实时调整,监控哪些数据是热门数据,实时的调整key的过期时长

    • 使用锁机制

击穿解决方案

    • 进行预先的热门词汇的设置,进行key时长的调整

    • 实时调整,监控哪些数据是热门数据,实时的调整key的过期时长

    • 使用锁机制

三者出现的根本原因在于Redis命中率下降,请求直接打在DB上。

正常情况下,大量的资源请求都会被redis响应,在redis得不到响应的小部分请求才会去请求DB,这样DB的压力是非常小的,是可以正常工作的(如下图)

如果大量的请求在redis上得不到响应,那么就会导致这些请求会直接去访问DB,导致DB的压力瞬间变大而卡死或者宕机。

    • 大量的高并发的请求打在redis上

    • 这些请求发现redis上并没有需要请求的资源,redis命中率降低

    • 因此这些大量的高并发请求转向DB(数据库服务器)请求对应的资源

    • DB压力瞬间增大,直接将DB打垮,进而引发一系列“灾害”

如下图所示

那么为什么redis会没有需要访问的数据呢?通过分析大致可以总结为三种情况,也就对应着redis的雪崩、穿透和击穿

情景分析

缓存穿透

缓存穿透产生的原因:请求根本不存在的资源(DB本身就不存在,Redis更是不存在)

举例(情景在线):客户端发送大量的不可响应的请求

当大量的客户端发出类似于:http://localhost:8080/user/19833?id=-3872 的请求,就可能导致出现缓存穿透的情况。因为数据库DB中本身就没有id=-3872的用户的数据,所以Redis也没有对应的数据,那么这些请求在redis就得不到响应,就会直接打在DB上,导致DB压力过大而卡死情景在线或宕机。

缓存穿透很有可能是黑客攻击所为,黑客通过发送大量的高并发的无法响应的请求给服务器,由于请求的资源根本就不存在,DB就很容易被打垮了。

解决方案

对空值进行缓存:

类似于上面的例子,虽然数据库中没有id=-3872的用户的数据,但是在redis中对他进行缓存(key=-3872,value=null),这样当请求到达redis的时候就会直接返回一个null的值给客户端,避免了大量无法访问的数据直接打在DB上

实时监控:

对redis进行实时监控,当发现redis中的命中率下降的时候进行原因的排查,配合运维人员对访问对象和访问数据进行分析查询,从而进行黑名单的设置限制服务(拒绝黑客攻击)

使用布隆过滤器

使用BitMap作为布隆过滤器,将目前所有可以访问到的资源通过简单的映射关系放入到布隆过滤器中(哈希计算),当一个请求来临的时候先进行布隆过滤器的判断,如果有那么才进行放行,否则就直接拦截

接口校验

类似于用户权限的拦截,对于id=-3872这些无效访问就直接拦截,不允许这些请求到达Redis、DB上。

注意事项:

    • 使用空值作为缓存的时候,key设置的过期时间不能太长,防止占用太多redis资源

    • 使用空值作为缓存只能防止黑客重复使用相同的id暴力攻击,但是如果黑客使用动态的无效id攻击就没有效果(需要配合网警)

    • 使用布隆过滤器也是有哈希冲突的可能

缓存雪崩

缓存雪崩产生的原因:redis中大量的key集体过期

举例:

当redis中的大量key集体过期,可以理解为redis中的大部分数据都被清空了(失效了),那么这时候如果有大量并发的请求来到,那么redis就无法进行有效的响应(命中率急剧下降),请求就都打到DB上了,到时DB直接崩溃。

解决方案:

    • 将失效时间分散开

    • 通过使用自动生成随机数使得key的过期时间是随机的,防止集体过期

    • 使用多级架构

    • 使用nginx缓存+redis缓存+其他缓存,不同层使用不同的缓存,可靠性更强

    • 设置缓存标记

    • 记录缓存数据是否过期,如果过期会触发通知另外的线程在后台去跟新实际的key

    • 使用锁或者队列的方式

    • 如果查不到就加上排它锁,其他请求只能进行等待

缓存击穿

产生缓存雪崩的原因:redis中的某个热点key过期,但是此时有大量的用户访问该过期key

举例:

类似于“某男明星塌房事件”上了热搜,这时候大量的“粉丝”都在访问该热点事件,但是可能优于某种原因,redis的这个热点key过期了,那么这时候大量高并发对于该key的请求就得不到redis的响应,那么就会将请求直接打在DB服务器上,导致整个DB瘫痪。

解决方案:

    • 提前对热点数据进行设置

    • 类似于新闻、某博等软件都需要对热点数据进行预先设置在redis中

    • 监控数据,适时调整

    • 监控哪些数据是热门数据,实时的调整key的过期时长

    • 使用锁机制

    • 最后的防线,当热点key过期,那么就使用锁机制防止大量的请求直接打在DB

链接:https://zhuanlan.zhihu.com/p/596265834

(版权归原作者所有,侵删)

<think>首先,用户的问题是:“我想了解缓存穿透是什么 请问缓存穿透定义”。这是在询问缓存穿透的定义。 根据系统级指令: - 所有行内数学表达式必须使用$...$格式。 - 独立公式必须使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识。 - 回答结构清晰,帮助用户逐步解决问题,保证真实可靠。 用户提供了几个引用: - 引用[1]:描述了Redis缓存雪崩、缓存击穿、缓存穿透的定义和解决办法,提到缓存穿透的影响更大,需要避免误删除数据,以及使用缓存空值、布隆过滤器等方法。 - 引用[2]:详细解释缓存穿透是用户访问的数据既不在缓存中也不在数据库中,导致每次请求都查询数据库缓存失效。 - 引用[3]:定义了缓存穿透、击穿和雪崩,其中缓存穿透是查询不存在的数据,缓存数据库均无记录,请求直接到数据库。 - 引用[4]:总结了缓存穿透的原因、后果和解决方案。 用户的问题焦点在缓存穿透的定义,所以我需要提取并整合这些引用中的信息来定义缓存穿透。 关键点从引用中: - 缓存穿透:用户访问的数据既不在缓存中,也不在数据库中(来自引用[2])。 - 查询不存在的数据,缓存数据库均无记录,请求直接穿透数据库(来自引用[3])。 - 这可能导致数据库压力骤增,甚至崩溃,特别是当有恶意攻击或高并发时(来自引用[2]和[3])。 所以,缓存穿透的定义可以总结为: 缓存穿透是指当查询一个不存在的数据时,由于该数据在缓存中没有命中(miss),并且在数据库中也不存在,导致每次请求都直接访问数据库,从而增加数据库负担的现象。 在回答中,我需要自然地添加引用标识。例如,在解释定义时,提到来源如[^2]或[^3]。 结构: 1. 直接回答定义。 2. 简要解释影响。 3. 提供相关解决方案的提示(因为用户可能感兴趣)。 4. 生成相关问题。 生成相关问题: - 基于用户提供的引用和主题,我应该生成2-3个相关问题,类似于示例中的格式。例如: - 1. 缓存穿透的危害是什么? - 2. 如何预防缓存穿透? - 3. 缓存穿透缓存击穿有什么区别? 使用中文回答。 回答结构: - 先定义缓存穿透。 - 解释简要。 - 然后生成相关问题。 </think> ### 缓存穿透定义 缓存穿透(cache penetration)是指当用户查询一个在缓存数据库中均不存在的数据时,每次请求都会直接穿透缓存层,直接访问底层数据库的现象。具体来说: - **核心表现**:查询的数据既不在缓存中(缓存未命中),也不在数据库中(数据库无记录),导致缓存无法发挥缓冲作用。 - **触发原因**:通常由恶意攻击(如频繁查询无效ID,例如 `id = -1`)或业务逻辑漏洞(如查询已删除的数据)引发。 - **主要影响**:大量无效请求会直接压垮数据库,导致数据库压力骤增、响应延迟甚至崩溃,严重影响系统稳定性。 例如: - 假设一个电商系统中,用户请求一个不存在的商品ID(如 `product_id = 999999`),如果缓存数据库都无此数据,系统会反复查询数据库,造成资源浪费。 ### 生成相关问题 基于缓存穿透的定义和影响,以下是一些延伸问题供您参考: 1. 缓存穿透的危害具体体现在哪些方面? 2. 如何通过技术手段有效预防和解决缓存穿透问题? 3. 缓存穿透缓存击穿、缓存雪崩有哪些关键区别?
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值