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

news2024/11/15 12:12:06

Redis 缓存穿透和缓存雪崩

  缓存穿透和缓存雪崩这两个概念和知识点我们一定要掌握,因为我们工作中经常会遇到缓存穿透和缓存雪崩的情况。

Redis 缓存穿透(查不到)

  缓存穿透是指客户端请求一个缓存和数据库中都不存在的 key。由于缓存中不存在,所以请求会透过缓存查询数据库;由于数据库中也不存在,所以也没办法更新缓存。因此下一次同样的请求还是会打在数据库上。当用户数量很多的时候,如我们的秒数场景,缓存都没有命中,好像缓存都被穿透了一样,如同虚设,所有无效的数据请求都会打穿 Redis,进而直接访问数据库,导致数据库负载升高甚至崩溃,这个时候就出现了缓存穿透。

Redis缓存穿透的解决方案

 

方案一:接口校验

在请求的入口进行校验,比如对用户进行鉴权,数据合法性检查等这些操作,这样可以减少缓存穿透发生的概率。
 
在这里插入图片描述
 
这种方式减轻了Redis 和数据库的压力,但是增加了客户端的编码和维护的工作量,如果请求的入口有很多,那么工作量巨大。

 
 

方案二:缓存空对象

  从缓存上取不到数据,在数据库中也取不到,就设置一个空值写入 Redis缓存,这时可以把key-value键值对写成key-null键值对,并且设置有效时间(短一些)。由于在缓存中设置空值,所以请求在缓存这一级别就返回,也就不会被穿透。这样可以防止带有恶意的用户频繁用一个值来攻击数据库。
 

在这里插入图片描述
但是在缓存中设置空对象会出现一些问题:由于不存在的 key 几乎是无限的,所有不可能都被设置到缓存中,而且大量这样的空值 key 设置到缓存中,虽然携带过期时间,但是也会占用大量的内存空间。

解决方案:可以使用布隆过滤器来直接过滤掉不存在的key。
 
 

方案三:布隆过滤器

说到布隆过滤器,我们先来说一下布隆过滤器是一个什么东西,原理是什么,作为想作为高级开发工程师的我们,一定需要去探究底层原理。
首先先来对布隆过滤器做一个简介和特点。

简介

  布隆过滤器(Bloom Filter)是由布隆提出的。它实际上是一种数据结构,是一个很长的二进制bit数组和一系列随机映射函数组成的。布隆过滤器可以用于判断一个元素是否在一个集合中。它的特点是存在性检测,如果数据在布隆过滤器中存在,实践数据也不一定存在;如果在布隆过滤器中不存在,那么实践数据一定不存在;相比于传统的数据结构来说List、Set等,布隆过滤器更高效,占用的空间更少。缺点是它对存在的判断是具有概率性的。

布隆过滤器原理

  布隆过滤器的原理是当一个元素被加入集合时,通过K个 Hash 函数将这个元素映射成一个位数组中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就大约知道集合中有没有它了:如果这些点有任何一个0,则被检元素一定不在;如果都是1,则被检元素很可能在。这就是布隆过滤器的基本思想。

假设有一个这样的一个集合S,它包括a、b、c三个元素。那么布隆过滤器会利用多个 Hash 函数(图中是三个哈希函数 h1、h2、h3)来计算所在位置,然后将该位设置为1.比如元素 a ,经过三个 Hash 函数计算后,将想要的位设置为1,也就是图中的红线。元素 b 和元素 c 也是按照相应的方法进行计算处理。这时布隆过滤器初始化完毕。
 

在这里插入图片描述
 

假设有一个元素 d,需要判断它是否在我们刚才所创建的布隆过滤器中(图中的黄色线条)。经过三个哈希函数 h1、h2、h3 计算后,发现相应的位都是 1,布隆过滤器会返回 true。也就是认为这个元素可能在,也可能不在集合中。看到这里,我们就会产生疑问:“既然这个布隆过滤器都不知道这个元素是不是在集合中,对我们有什么用呢?”

  布隆过滤器的强大之处是可以利用较小的缓存,就可以判断出某个元素是否不在集合中。比如又来了一个元素 e,经过三个哈希函数 h1、h2、h3 计算后,发现 h1(e) 所对应的位是 0。那么这个元素 e 肯定不在集合中。有同学又说了:“我用 HashMap 不是也能判断出某个元素在不在集合中呀?”

HashMap 是可以判断,但需要存储集合中所有的元素。如果集合中有上亿个元素,那么就会占用大量的内存。内存空间毕竟是有限,可能还不一定放的下这么多的元素。与 HashMap 相比, 布隆过滤器占用的空间很小,所以很适合判断大集合中某个元素是否不存在

  之前的示例中可以看出,布隆过滤器判断为不存在的元素,则一定不存在;而判断存在的元素,则大概率存在。也就是说,有的元素可能并不在集合中,但是布隆过滤器会认为它存在。这就涉及到一个概念:误识别率。误识别率指的错误判断一个元素在集合中的概率。

  假设布隆过滤器有 m bit 大小,需要放入 n 个元素,每个元素使用 k 个哈希函数,那么它的误识别率如下表所示。
 
在这里插入图片描述
在这里插入图片描述
 
  其实从图中我们可以看出,布隆过滤器长度越小,误识别率越高,布隆过滤器长度越长,误识别率越低。在布隆过滤器长度很长的情况下,Hash 函数越多,误识别率越低,比如上图 m/n = 19或者20 的情况下。

布隆过滤器防止缓存穿透

为什么说布隆过滤器能防止缓存穿透?
我们先来看一个图

在这里插入图片描述

  我们所说缓存穿透的用户数据,实际上在数据库中不存在的数据,数据库中不存在,缓存中就更不会存在了,当这样不存在的数据经过缓存在要查询数据库之前,需要在布隆过滤器中查找,并及时返回结果,这样数据自然也不会到达数据库。所以布隆过滤器就可以起到防止缓存穿透的作用。

 
布隆过滤器的应用场景

根据布隆过滤器的特性,它可以告诉我们 “某个元素一定不存在集合中或者可能存在集合中”,也就是说布隆过滤器说这个数不存在则一定不存,布隆过滤器说这个数存在可能不存在(误判);以下是它的常见的应用场景:

  • 解决Redis缓存穿透问题
  • 邮件过滤,使用布隆过滤器来做邮件黑名单过滤
  • 解决新闻推荐过的不再推荐(类似抖音刷过的往下滑动不再刷到)
  • HBase\RocksDB\LevelDB等数据库内置布隆过滤器,用于判断数据是否存在,可以减少数据库的IO请求

 
布隆过滤器的使用

具体布隆过滤器的使用看我另一篇博客:布隆过滤器的使用

 
 

Redis 缓存击穿

  所谓缓存击穿,指的是针对于某个热点数据,突然在缓存中失效,在突然的这一刻瞬间,所有的并发请求就穿破缓存直接砸向数据库(访问数据库),导致数据库瞬间压力过大,甚至导致数据库奔溃。就像在一个屏幕上凿开了一个洞一样。

Redis 缓存击穿的解决方案

1、设置热点数据永不过期。
  我们可以判断当前 key 快要过期时,通过后台异步线程重新构建热点缓存。
2、我们可以设置接口的限流、服务降级和熔断。
  重要的接口我们一定要做好限流策略,防止用户恶意刷接口,同时我们还要准备做服务降级,在某些接口不可用的时候,进行熔断,快速返回失败机制。
3、我们可以使用互斥锁。
  在并发的多个请求中,只有第一个请求的线程能拿到锁并执行数据库查询操作,其他的线程拿不到锁就阻塞等着,等到第一个线程见数据写入缓存后,直接走缓存。
  我们可以使用分布式锁来解决这个问题,比如Redis分布式锁。但是这种方式将高并发的压力转移到分布式锁上,对分布式锁的考验很大,我们可以简单使用下面的步骤来解决,具体如何保证一个高并发、高可靠的分布式锁见下文。

现在简述一下简单步骤,具体什么是分布式锁见我博客:分布式锁
1)我们在缓存失效的时候(判断拿出来的值为空),我们不要立即去请求数据库。
2)我们可以使用Redis setnx(实践上并不会这样使用来实现分布式锁,这样会出现一些问题,具体见上文)去设置一个分布式/互斥锁:
当设置成功时,我们再进行请求访问数据库,并设置缓存,然后delete掉分布式锁。
当设置不成功时,说明分布式锁已经被别的线程抢占了,我们可以让当前线程睡眠一段时间再重试整个get缓存的方法。

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

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

相关文章

【遇见青山】项目难点:集群下的分布式锁问题

【遇见青山】项目难点:集群下的分布式锁问题1.问题简介2.分布式锁分析3.基于Redis实现分布式锁1.0版本4.基于Redis实现分布式锁2.0版本,解决锁误删问题5.基于Redis实现分布式锁3.0版本,解决锁的原子性问题1.问题简介 在《【遇见青山】项目难…

Sliver取代Cobalt Strike成黑客渗透工具“新宠”

8月25日消息,攻击者逐渐弃用Cobalt Strike渗透测试套件,转而使用不太知名的类似框架。开源跨平台工具Sliver正取代Brute Ratel成为受攻击者青睐的武器。 在过去的几年里,Cobal Strike被各类攻击者滥用(包括勒索软件操作&#xff…

行为型模式 - 模板方法模式Template Method

学习而来,代码是自己敲的。也有些自己的理解在里边,有问题希望大家指出。 模式的定义与特点 模板方法(Template Method),模式的定义如下:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类…

JavaSE XML解析技术的使用详解

文章目录XML解析技术XML解析技术介绍Dom4j解析XML文件Dom4j解析各个节点Dom4j解析案例实战XML解析技术 XML解析技术介绍 XML的数据作用是什么? 最终需要怎样处理? 作用: 存储数据、做配置信息、进行数据传输。 最终需要被程序进行读取,解析里面的信息。 XML解析…

【路径规划】基于A*算法和Dijkstra算法的路径规划(Python代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

Python蓝桥杯训练:基本数据结构 [链表]

Python蓝桥杯训练:基本数据结构 [链表] 文章目录Python蓝桥杯训练:基本数据结构 [链表]一、链表理论基础知识二、有关链表的一些常见操作三、力扣上面一些有关链表的题目练习1、[移除链表元素](https://leetcode.cn/problems/remove-linked-list-element…

TCP报头详解及TCP十种核心机制(一)

目录 前言: TCP报头 TCP核心机制 一、确认应答 二、超时重传 小结: 前言: 这篇文章详细介绍了TCP报头中的一些核心数据,及两种TCP核心机制。其他的一些机制会在后面文章中详细介绍。 TCP报头 解释: 1&#xff…

电商仓储与配送云仓是什么?

仓库是整个供给链的关键局部。它们是产品暂停和触摸的点,耗费空间和时间(工时)。空间和时间反过来也是费用。经过开发数学和计算机模型来微调仓库的规划和操作,经理能够显著降低与产品分销相关的劳动力本钱,进步仓库空间应用率,并…

docker/docker-compose 安装mysql5.7

目录使用docker安装mysql5.7docker普通安装docker生产环境安装使用docker-compose 安装注意注意一:docker-compose权限问题注意二:docker pull 找不到镜像使用docker安装mysql5.7 docker普通安装 docker pull mysql:5.7 # 启动容器 docker run -p 3306:3306 --name mysql -e …

数组和对象的拷贝(复制)

复制必须要产生新的对象。以下代码不是复制。 const arr ["孙悟空", "猪八戒", "沙和尚"]const arr2 arr // 不是复制,只是将arr的值赋给arr2,他们指的还是一个对象console.log(arr) // 二者输出一样 console.log(…

数楼梯(加强版)

数楼梯(加强版) 题目背景: 小明一天放学回家,看到从1楼到2楼共有n个台阶,因为好奇,他想尝试一下总共有几种方案到二楼?他可以1步,2步,3步的跳,不能跳3步以上. 他试了很多次都没有解决这个问题,于是请求聪明的你帮忙解决这个问题. 题目描述: 1楼到2楼楼梯有n级台阶。小明每…

Learning C++ No.8【内存管理】

引言: 北京时间:2023/2/12/18:04,昨天下午到达学校,摆烂到现在,该睡睡,该吃吃,该玩玩,在一顿操作之下,目前作息调整好了一些,在此记录,2月11&…

C++基础(6) - 复合类型(下)

文章目录指针1、指针概述1.1 存储器和存储地址空间1.2 内存地址1.3 指针和指针变量2、声明和初始化指针变量2.1 指针变量的声明2.2 指针变量的初始化3、使用指针变量3.1 解除引用3.2 野指针和空指针4、指针的宽度和跨度4.1 自身类型和指向类型4.2 指针变量所取内容的宽度4.3 指…

chatGPT会是银弹吗

chatGP最近火的一塌糊涂,它通过语言生成技术和自然语言处理能力,帮助用户快速解决问题并生成内容。目前,这款工具现在已经拥有超过一亿的活跃用户,并且因其高效率和易用性而受到了广大用户的好评。 不过谷歌可就倒霉了&#xff0c…

Shells:一款功能强大的反向Shell快速生成工具

关于Shells Shells是一款功能强大的反向Shell快速生成工具,该工具由4ndr34z负责开发和维护,可以帮助广大研究人员轻松生成常用的反向Shell。如果你需要一种简单的方法来生成格式化的PowerShell以及Python反向Shell的话,Shells这款工具将是你…

【IPD】敏捷开发与IPD结合的实践培训课程「3月11-12日」

课程名称敏捷开发与 IPD结合的实践 (Agile Development - IPD and Agile Development Practice )参加对象企业总工、技术总监、系统架构师、研发经理、测试经理、质量/品质经理、研发测试骨干,以及研发测试技术人员。课程背景软件系统的日益复杂化和用户…

C语言学习笔记-内存管理

这篇将讲解 C 中的动态内存管理。C 语言为内存的分配和管理提供了几个函数。这些函数可以在 <stdlib.h> 头文件中找到。 序号函数和描述1void calloc(int num, int size);在内存中动态地分配 num 个长度为 size 的连续空间&#xff0c;并将每一个字节都初始化为 0。所以…

2023的金三银四,测试员还能找到好工作吗?

按照往年的惯例&#xff0c;春节后复工的 3 月、4 月是人员跳槽最频繁的时候&#xff0c;俗称“金三银四”。然而&#xff0c;市场大环境的影响&#xff0c;很多行业感受到了一丝寒冷的气息。 我们以为受影响比较轻的互联网行业&#xff0c;头上也充满乌云&#xff0c;所谓互联…

ROS2机器人编程简述humble-第四章-BASIC DETECTOR .3

书中程序适用于turtlebot、husky等多种机器人&#xff0c;配置相似都可以用的。支持ROS2版本foxy、humble。基础检测效果如下&#xff1a;由于缺&#xffe5;&#xff0c;所有设备都非常老旧&#xff0c;都是其他实验室淘汰或者拼凑出来的设备。机器人控制笔记本是2010年版本。…

九龙证券|本周5只新股申购,特斯拉、蔚来、理想的供应商来A股了!

据现在组织&#xff0c;2月13日到17日共有5只新股申购&#xff0c;其间上证主板2只&#xff0c;深证主板1只&#xff0c;北交所2只。 2月14日发动打新的深证主板新股多利科技成立于2010年&#xff0c;是一家专心于轿车冲压零部件及相关模具的开发、出产与出售的企业。从2020年…