【进阶篇】Redis缓存击穿, 穿透, 雪崩, 污染详解

【进阶篇】Redis缓存穿击, 穿透, 雪崩, 污染详解

文章目录

  • 【进阶篇】Redis缓存穿击, 穿透, 雪崩, 污染详解
  • 0. 前言
    • 大纲
    • 缓存穿击
    • 缓存穿透
    • 缓存雪崩
    • 缓存污染
  • 1. 什么是缓存穿透?
    • 1.1. 发生原因
    • 1.2. 导致问题
    • 1.3. 解决方案
  • 2. 什么是缓存击穿
    • 3.1. 发生原因
    • 3.1. 解决方案
  • 3. 什么是缓存雪崩
    • 3.1. 缓存雪崩通常发生原因
    • 3.2. 缓存雪崩的解决方案
  • 4. 什么是缓存污染
    • 4.1. 发生原因
    • 4.2. 导致问题:
    • 4.3. 缓存污染的解决方案包括:
  • 5.参考资料

在这里插入图片描述

0. 前言

背景:有个社群网友说面试的时候,在Redis 缓存环节,面试官抽风,问了他一些缓存常见问题,瞬间懵逼,关于Redis缓存穿击, 穿透, 雪崩,
污染导致的原因和预防措施,本文从网络上搜接了一些概念和解释。希望大家能吊打八股文面试官。

大纲

在这里插入图片描述

缓存穿击

  • 定义:攻击者针对不存在的数据不断发送请求,导致缓存层无法命中,从而对数据库层造成压力。
  • 解决方案:
    • 在缓存中设置空值占位符,避免频繁访问数据库。
    • 增加布隆过滤器,判断请求的Key是否有效。

缓存穿透

  • 定义:攻击者针对不存在的数据发送请求,绕过缓存直接访问数据库,导致数据库压力过大。
  • 解决方案:
    • 在查询结果为空时,也将结果缓存起来,设置一个较短的过期时间,避免频繁访问数据库。
    • 增加布隆过滤器,判断请求的Key是否有效。

缓存雪崩

  • 定义:缓存层的大面积失效,所有的请求都直接访问数据库,导致数据库压力过大。
  • 解决方案:
    • 设置多级缓存,避免单点故障。
    • 设置不同的缓存过期时间,避免同一时间大量缓存失效。
    • 使用限流、熔断等机制,控制访问量,避免一次性大量请求击穿缓存。

缓存污染

  • 定义:缓存中出现了异常、非法或非预期的数据,导致后续读取到的数据不正确。
  • 解决方案:
    • 增加数据校验机制,比如使用CRC校验码。
    • 限制缓存写入,只有满足一定条件(如过滤非法字符)的数据才能写入缓存。
    • 使用布隆过滤器判断数据是否有效。

1. 什么是缓存穿透?

缓存穿透是指在缓存系统中,大量的请求查询一个缓存中不存在的数据,导致这些请求都绕过了缓存层,直接查询数据库或其他存储系统。这种情况下,缓存无法提供任何帮助,而且频繁访问数据库可能会对系统的性能和稳定性产生负面影响。

1.1. 发生原因

  1. 查询一个不存在的数据:用户查询一个在数据库中不存在的数据,例如查询一个无效的用户ID或者非法的URL参数。

  2. 恶意攻击:黑客或恶意用户故意发送大量的查询请求,查询缓存中不存在的数据,以达到对系统的拒绝服务攻击。
    在这里插入图片描述

1.2. 导致问题

缓存穿透可能导致以下问题:

  1. 增加系统负载:缓存穿透会导致大量的请求直接访问数据库或其他存储系统,而不经过缓存,这会增加这些系统的负载,降低系统的性能和响应速度。

  2. 数据库压力增大:由于缓存穿透导致大量的请求直接访问数据库,数据库的负载会大幅增加,可能导致数据库性能下降,甚至发生数据库宕机等故障。

  3. 数据不一致:如果缓存穿透导致请求直接访问数据库,而数据库中的数据发生了变化,但缓存中的数据仍然是过期或无效的,这会导致返回的数据与实际数据不一致,可能引发业务逻辑错误或显示错误的信息。

1.3. 解决方案

  1. 空结果缓存:对于查询结果为空的情况,将空结果进行缓存,并设置一个较短的过期时间。这样再次查询相同的数据时可以直接命中缓存,避免绕过缓存直接查询数据库。

  2. 布隆过滤器:使用布隆过滤器进行预先过滤,将可能存在的数据的key进行判断,如果布隆过滤器判断某个数据的key不存在,可以直接返回空结果,避免对数据库进行查询。
    这是比较推荐的方法。所谓布隆过滤器,就是一种数据结构,它是由一个长度为m bit的位数组与n个hash函数组成的数据结构,位数组中每个元素的初始值都是0。在初始化布隆过滤器时,会先将所有key进行n次hash运算,这样就可以得到n个位置,然后将这n个位置上的元素改为1。这样,就相当于把所有的key保存到了布隆过滤器中了。

举个例子,比如我们一共有3个key,我们对这3个key分别进行3次hash运算,key1经过三次hash运算后的结果分别为2/6/10,那么就把布隆过滤器中下标为2/6/10的元素值更新为1,然后再分别对key2和key3做同样操作,结果如下图:在这里插入图片描述

这样,当客户端查询时,也对查询的key做3次hash运算得到3个位置,然后看布隆过滤器中对应位置元素的值是否为1,如果所有对应位置元素的值都为1,就证明key在库中存在,则继续向下查询;如果3个位置中有任意一个位置的值不为1,那么就证明key在库中不存在,直接返回客户端空即可。如下图:
在这里插入图片描述

当客户端查询key4时,key4的3次hash运算中,有一个位置8的值为0,就说明key4在库中不存在,直接返回客户端空即可。

所以,布隆过滤器就相当于一个位于客户端与缓存层中间的拦截器一样,负责判断key是否在集合中存在。如下图:

在这里插入图片描述

布隆过滤器的好处就是解决了第一种缓存空值的不足,但布隆过滤器也存在缺陷,首先,它有误判的可能,比如在上面客户端查询key4的图中,假如key4经过3次hash运算得到的位置分别是2/4/6,由于这3个位置的值都是1,所以,布隆过滤器就认为key4在库中存在,进而继续向下查询了。所以,布隆过滤器判断存在的key实际上可能是不存在的,但布隆过滤器判断不存在的key是一定不存在的。它的第二个缺点就是删除元素比较难,比如现在要删除key2这个元素,那么需要将2/7/11三个位置的元素值改为0,但这样就会影响到key1和key3的判断。

  1. 缓存穿透检测:在查询数据之前,先在缓存中检查该数据是否存在,如果缓存中不存在该数据,则直接返回空结果。这样可以避免频繁查询数据库,减轻数据库的负载。

通过以上解决方案,可以有效地防止缓存穿透问题,提高系统的性能和稳定性。

2. 什么是缓存击穿

在这里插入图片描述
缓存击穿是指在缓存系统中,一个热点数据过期或者被删除后,恰好有大量的并发请求同时查询该数据,导致这些请求都绕过了缓存层,直接查询数据库或其他存储系统。这种情况下,缓存无法提供任何帮助,而且频繁访问数据库可能会对系统的性能和稳定性产生负面影响。

3.1. 发生原因

  1. 热点数据失效:一个热点数据在缓存中的过期时间到期或被删除,此时有大量并发请求同时查询该数

3.1. 解决方案

  1. 加锁机制:在查询缓存失效后,只允许一个请求访问数据库,其他请求等待结果。当第一个请求查询到数据后,将数据写入缓存,并释放锁,其他请求从缓存中获取数据。 在这里插入图片描述

  2. 异步更新缓存:在查询缓存失效后,第一个请求查询数据库,并将查询到的数据异步更新到缓存,其他请求等待缓存更新完成后再从缓存中获取数据。
    在这里插入图片描述

  3. 提前加载热点数据:在系统启动或者低峰期,预先加载热点数据到缓存中,避免在高峰期突然失效而引起缓存击穿。

3. 什么是缓存雪崩

缓存雪崩是指在缓存系统中,大量的缓存数据同时失效或者被删除,导致所有的请求都直接访问数据库或其他存储系统,从而造成系统的瞬时压力过大,甚至导致系统瘫痪。与缓存击穿不同的是,缓存雪崩是指大规模的缓存失效,而非单个热点数据失效。
在这里插入图片描述

3.1. 缓存雪崩通常发生原因

  1. 缓存过期时间设置不合理:如果缓存中大量的数据同时设置了相同的过期时间,那么当这些数据同时过期时,会导致缓存雪崩。

  2. 缓存数据集中在同一台服务器或同一片区域:如果缓存数据集中在同一台服务器或同一片区域,当该服务器或该区域发生故障或网络异常时,会导致缓存雪崩。

  3. 缓存服务器宕机或重启:如果缓存服务器宕机或重启,那么所有的缓存数据都会丢失,导致缓存雪崩。

3.2. 缓存雪崩的解决方案

  1. 设置合理的缓存过期时间:合理地设置缓存数据的过期时间,避免大量的数据同时过期。

  2. 分散缓存失效时间:将缓存数据的过期时间随机分布,避免大量数据同时过期。

  3. 使用多级缓存:在系统架构中引入多级缓存,将缓存数据分散到不同的缓存服务器或缓存区域,减少单一故障点。

  4. 引入热点数据预热:在系统启动或者低峰期,预先加载热点数据到缓存中,避免在高峰期突然失效而引起缓存雪崩。

4. 什么是缓存污染

缓存污染是指在缓存系统中,由于错误的缓存配置或缓存数据异常,导致缓存中存储了无效或错误的数据,进而影响系统的正常运行。

4.1. 发生原因

  1. 缓存键冲突:不同的数据存储在缓存中使用了相同的缓存键,导致缓存数据被覆盖或混淆。这可能是由于不同的数据模块使用了相同的缓存键,或者在缓存键生成逻辑中存在错误。

  2. 缓存数据异常:缓存数据在存储或读取过程中出现异常,例如数据格式错误、数据丢失、数据损坏等。如果这些异常数据被存储到缓存中,将导致后续的请求获取到错误的数据。

  3. 缓存穿透:由于恶意攻击或异常情况,大量的请求访问缓存系统中不存在的数据,导致这些请求直接访问数据库或其他存储系统,而不是从缓存中获取数据。

4.2. 导致问题:

  1. 返回错误的数据:当缓存中存储了错误的数据时,后续的请求获取到的数据将是错误的,可能导致系统的功能异常或显示错误的信息。

  2. 增加系统负载:如果大量的请求绕过缓存直接访问数据库或其他存储系统,将会增加这些系统的负载,降低系统的性能和响应速度。

4.3. 缓存污染的解决方案包括:

  1. 缓存键设计合理:确保不同的数据模块使用不同的缓存键,避免缓存键冲突。

  2. 数据校验和容错处理:在缓存数据存储和读取过程中,进行数据校验,确保数据的完整性和准确性。对于异常数据,可以进行容错处理,例如删除或重新获取正确的数据。

  3. 缓存穿透防护:使用布隆过滤器等技术,对于不存在的数据进行预判,避免无效请求直接访问存储系统。

5.参考资料

  1. Redis官方文档:https://redis.io/
  2. Redis实战(书籍)
  3. Redis设计与实现(书籍)
  4. https://www.toutiao.com/article/7088132873051488780/

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

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

相关文章

Spring-Cloud-Openfeign如何传递用户信息?

用户信息传递 微服务系统中,前端会携带登录生成的token访问后端接口,请求会首先到达网关,网关一般会做token解析,然后把解析出来的用户ID放到http的请求头中继续传递给后端的微服务,微服务中会有拦截器来做用户信息的…

PY32F003F18端口复用功能映射

PY32F003F18端口复用功能映射,GPIO引脚可配置为"输入,输出,模拟或复用功能。 一、端口A复用功能映射 端口A复用功能映射表里,每个引脚都有AF0~AF15,修改AF0~AF15的值,就可以将对应复用用能引脚映射到CPU引脚上。…

leetcode 925. 长按键入

2023.9.7 我的基本思路是两数组字符逐一对比,遇到不同的字符,判断一下typed与上一字符是否相同,不相同返回false,相同则继续对比。 最后要分别判断name和typed分别先遍历完时的情况。直接看代码: class Solution { p…

【业务功能篇99】微服务-springcloud-springboot-电商订单模块-生成订单服务-锁定库存

八、生成订单 一个是需要生成订单信息一个是需要生成订单项信息。具体的核心代码为 /*** 创建订单的方法* param vo* return*/private OrderCreateTO createOrder(OrderSubmitVO vo) {OrderCreateTO createTO new OrderCreateTO();// 创建订单OrderEntity orderEntity build…

[HNCTF 2022] web 刷题记录

文章目录 [HNCTF 2022 Week1]easy_html[HNCTF 2022 Week1]easy_upload[HNCTF 2022 Week1]Interesting_http[HNCTF 2022 WEEK2]ez_SSTI[HNCTF 2022 WEEK2]ez_ssrf[HNCTF 2022 WEEK2]Canyource [HNCTF 2022 Week1]easy_html 打开题目提示cookie有线索 访问一下url 发现要求我们…

mybatisplus多租户原理略解

概述 当前mybatisPlus版本 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.2</version> </dependency>jdk版本&#xff1a;17 springboot版本&#xff1a;…

深入探讨Kubernetes(K8s)在云原生架构中的关键作用和应用

文章目录 1. 容器化的应用程序管理2. 自动化扩展和负载均衡3. 容器编排和调度4. 存储管理5. 自动化滚动更新6. 多云和混合云部署7. 监控和日志8. 安全9. 社区支持和生态系统10. 未来展望案例 &#x1f388;个人主页&#xff1a;程序员 小侯 &#x1f390;CSDN新晋作者 &#x1…

2023年高教社杯全国大学生数学建模竞赛参赛事项注意

MathClub数模资源&#xff0c;含专属思路 资源链接&#xff1a;点击这里获取众多数模资料、思路精讲、论文模板latex和word、学习书籍等 2023高教社杯数学建模国赛–赛前准备 一年一度的数学建模国赛要来啦&#xff01;&#xff01;&#xff01;小编仔细阅读了比赛官方网站上…

【请求报错:javax.net.ssl.SSLHandshakeException: No appropriate protocol】

1、问题描述 在请求服务时报错说SSL握手异常协议禁用啥的&#xff0c;而且我的连接数据库的url也加了useSSLfalse javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)2、解决方法 在网上查找了方法…

LeetCode 1004.最大连续1的个数

题目链接 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 题目解析 硬往题目介绍上边去想的话其实非常困难&#xff0c;如果换种方式思考就会简单许多。 若我们将思想转化为&#xff0c;找出最长的子串(里面含有的0的数量最大为k)&#xff0c;然后返…

QT实现任意阶贝塞尔曲线绘制

bezier曲线在编程中的难点在于求取曲线的系数&#xff0c;如果系数确定了那么就可以用微小的直线段画出曲线。bezier曲线的系数也就是bernstein系数&#xff0c;此系数的性质可以自行百度&#xff0c;我们在这里是利用bernstein系数的递推性质求取&#xff1a; 简单举例 两个…

运维Shell脚本小试牛刀(七):在函数文脚本件中调用另外一个脚本文件中函数|函数递归调用|函数后台执行

运维Shell脚本小试牛刀(一) 运维Shell脚本小试牛刀(二) 运维Shell脚本小试牛刀(三)::$(cd $(dirname $0)&#xff1b; pwd)命令详解 运维Shell脚本小试牛刀(四): 多层嵌套if...elif...elif....else fi_蜗牛杨哥的博客-CSDN博客 Cenos7安装小火车程序动画 运维Shell脚本小试…

【扩散模型 李宏毅B站教学以及基础代码运用】

李宏毅教学视频&#xff1a; Link1 B站DDPM公式推导以及代码实现&#xff1a; Link2 这个视频里面有论文里面的公式推导&#xff0c;并且1小时10分开始讲解实例代码。 文章目录 扩散模型概念&#xff1a;Diffusion Model工作原理&#xff1a;影像生成模型本质上的共同目标B站…

算法——组合程序算法解析

组合就是从m个元素的数组中求n个元素的所有组合&#xff0c;代码如下&#xff1a; #include <iostream> #include <vector> using namespace std; // 递归求解组合 void combinations(vector<int>& nums, vector<int>& combination, int star…

Linux 安装 JDK

要在Linux上安装JDK 1&#xff0c;按照以下步骤进行操作&#xff1a; 1. 下载JDK安装文件&#xff1a;首先&#xff0c;你需要找到适用于你操作系统的JDK安装文件&#xff08;tar.gz或tar.bz2格式&#xff09;。你可以从Oracle官方网站或其他可信的来源下载该文件。 2. 解压…

Ansible自动化运维

目录 前言 一、概述 常见的开源自动化运维工具比较 二、ansible环境搭建 三、ansible模块 &#xff08;一&#xff09;、hostname模块 &#xff08;二&#xff09;、file模块 &#xff08;三&#xff09;、copy模块 &#xff08;四&#xff09;、fetch模块 &#xff…

借助各大模型的优点生成原创视频(真人人声)Plus

【技术背景】 众所周知&#xff0c;组成视频的3大元素&#xff0c;即文本语音图片。接着小编逐一介绍生成原创视频的过程。 【文本生成】 天工AI搜索&#xff08;thttp://iangong.cn&#xff09; 直接手机短信验证就可以使用&#xff0c;该大模型已经接入互联网&#xff0c…

什么是IIFE(Immediately Invoked Function Expression)?它有什么作用?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐IIFE 的基本语法⭐IIFE 的主要作用⭐如何使用 IIFE 来创建私有变量和模块封装⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅…

GOOGLE SRE 运维模式解读

一、SRE核心是什么 我总结下来是&#xff1a;通过软件工程的方式开发&#xff08;GOOGLE规定SRE团队必须将50%的精力花在真实的开发工作上&#xff09;一些自动化的工具系统来解放传统运维工程师大量重复和手工操作&#xff0c;从而让新生代的SRE工程师有更多的时间&#xff1…

五种定时任务方案(Timer+ScheduleExecutorService+spring task+多线程执行+quartz)

方案一&#xff1a;Timer (1)Timer.schedule(TimerTask task,Date time)安排在制定的时间执行指定的任务。 (2)Timer.schedule(TimerTask task,Date firstTime ,long period)安排指定的任务在指定的时间开始进行重复的固定延迟执行&#xff0e; (3)Timer.schedule(TimerTask…