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

news2025/1/10 11:38:35

【进阶篇】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.coloradmin.cn/o/981884.html

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

相关文章

PHP自己的框架留言板功能实现

目录 1、实现留言板功能效果 2、创建留言板数据表 3、控制器提交和显示方法 4、提交留言板html 5、留言板列表html 1、实现留言板功能效果 2、创建留言板数据表 CREATE TABLE msg (id int(11) NOT NULL AUTO_INCREMENT,name varchar(30) DEFAULT NULL COMMENT 留言板姓…

FullGC 40 次/天优化为 10 天 1 次

问题 前一段时间,线上服务器的 FullGC 非常频繁,平均一天 40 多次,而且隔几天就有服务器自动重启了,这表明服务器的状态已经非常不正常了,得到这么好的机会,当然要主动请求进行调优了。 未调优前的服务器 GC 数据,FullGC 非常频繁。 首先服务器的配置非常一般(2 核 4…

公园气象站:用科技力量,感知气象变化

在城市的喧嚣中,公园成为人们休闲娱乐的宁静之地。而在这些公园中的公园气象站静静地矗立着,不仅为公园的日常运营提供着重要数据,还在为游客的安全保驾护航。 用科技力量,感知气象变化 科技的创新为气象监测提供了更为精准的手…

iOS 16.4更新指南:问题解答与新功能一览

我应该更新到iOS 16.4吗?这是许多iPhone用户在新更新可用时问自己的一个常见问题。最新的iOS版本提供了各种功能和改进,因此更新的诱惑力很大。 但是,在更新之前,你应该考虑几个因素,以确保安装过程顺利成功。这些因素…

Android 九宫格布局

效果图 实现思路: 1.使用GridView来实现九宫格布局,设置numColumns3。 2.图标使用的是Font Awesome矢量图标,详情可以参考Android 在APP中使用 Font Awesome 图标_.fa-headphones_清山博客的博客-CSDN博客 实现步骤: 1.布局文…

关于vscode的GitLens插件里的FILE HISTORY理解

最近在用vscode的GitLens插件开发项目遇到这个疑问,先看图: 每当我点击FILE HISTORY 一个commit时,正常来说显示器会自动将点击的提交版本和它上一个提交版本进行比较,如果单纯这么理解的话就错了,因为GitLens的File …

基于循环队列和信号量的生产和消费者模型

这一节为什么要基于信号量来实现同一个模型,原因: void push(const T& in){pthread_mutex_lock(&_lock);while(is_Full()){//这里说明阻塞队列是满的,需要让生产者等待pthread_cond_wait(&_pcond,&_lock);}//这里说明阻塞队列…

jupyter 格式化与快捷键

1、标题: # 一级标题 ## 二级标题 ### 三级标题 2、 加粗文本: **加粗文本** 3、斜体文本: _斜体_ 4、删除线 ~删除线~ 5、高亮文本 高亮文本 6、区块引用 > 我是引用文字 >> 我是第二层 >&g…

提高广播新闻自动语音识别模型的准确性

语音识别技术的存在让机器能够听懂人类的语言,让机器理解人类的语言。语音识别技术发展至今,已经应运而上了各种各样的语音智能助手,可能有一天我们身边的物体都能和我们说话,万物相连的时代也如期而至。 数据从何而来&#xff1…

FPN模型

【简介】 2017年,T.-Y.Lin等人在Faster RCNN的基础上进一步提出了特征金字塔网络FPN(Feature Pyramid Networks)技术。在FPN技术出现之前,大多数检测算法的检测头都位于网络的最顶层(最深层),虽说最深层的特征具备更丰富的语义信息&#xff0…

Mybatis 动态SQL - 使用foreach标签查询数据、批量新增、批量修改、删除数据

前面我们介绍了使用Mybatis完成数据的增删改查,并且也了解了如何在Mybatis中使用JDK的日志系统打印日志;本篇我们介绍使用Mybatis的动态SQL完成查询数据、批量新增、批量修改、删除数据。 如果您对数据的增删改查操作和Mybatis集成JDK日志系统不太了解&…

基于FPGA的RGB图像转化为灰度图实现,通过MATLAB进行辅助验证

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 vivado2019.2 matlab2022a 3.部分核心程序 timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 202…

js中添加屏蔽F12 审查元素、屏蔽开发者工具、屏蔽右键菜单、屏蔽剪切、屏蔽选中操作

在看某个网站时,看到一段话想复制一下,结果复制不了。想打开F12看看元素进行复制,也不行,没有反应。最后通过打开开发者工具看看,结果一打开就跳到about:blank。 看到这操作一脸懵逼,小样的,还有…

iPhone15就要到来,iPhone14可能会铺天盖地地降价

智能手机并没有变得更便宜,这就是为什么如果你在购买新设备,值得记住去年的型号。苹果即将推出的iPhone 15系列预计将于本月发布,有传言称9月12日将举行苹果活动。当他们真的宣布时,我们很可能也会看到iPhone 14的价格在iPhone 15…

【项目经验】elementui抽屉(从下到上方向)实现向上拉伸

效果图 直接上代码 <template><div><el-button click"drawerBtn" type"primary" style"margin-left: 16px;">点我打开</el-button><el-drawer title"我是标题" :modal"false" :wrapperClosable…

centos7 下使用docker安装常见的软件:Redis

关于docker的基础知识&#xff0c;请见《别在说自己不知道docker了&#xff0c;全文通俗易懂的给你说明白docker的基础与底层原理》 在自己学习的过程中经常会需要动手安装一下常见的工具&#xff0c;本篇就手把手带你用docker安装一遍。 jdk安装 如果先要更换之前的jdk从第…

汽车级肖特基二极管DSS220-Q 200V 2A

DSS220-Q是什么二极管&#xff1f;贵司有生产吗&#xff1f; 肖特基二极管DSS220-Q符合汽车级AEC Q101标准吗&#xff1f; DSS220-Q贴片肖特基二极管参数是什么封装&#xff1f;正向电流和反向电压是多大&#xff1f; DSS220-Q肖特基二极管需要100KK&#xff0c;有现货吗&#…

LeetCode 48题: 旋转图像

题目 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]]…

LeetCode刷题笔记【24】:贪心算法专题-2(买卖股票的最佳时机II、跳跃游戏、跳跃游戏II)

文章目录 前置知识122.买卖股票的最佳时机II题目描述贪心-直观写法贪心-优化代码更简洁 55. 跳跃游戏题目描述贪心-借助ability数组贪心-只用int far记录最远距离 45.跳跃游戏II题目描述回溯算法贪心算法 总结 前置知识 参考前文 参考文章&#xff1a; LeetCode刷题笔记【23】…

Ansible-roles学习

目录 一.roles角色介绍二.示例一.安装httpd服务 一.roles角色介绍 roles能够根据层次型结构自动装载变量文件&#xff0c;tasks以及handlers登。要使用roles只需在playbook中使用include指令即可。roles就是通过分别将变量&#xff0c;文件&#xff0c;任务&#xff0c;模块以…