Redis缓存穿透、击穿和雪崩

news2024/11/27 14:48:19

1、Redis缓存穿透

缓存穿透是指当用户在查询一条数据的时候,而此时数据库和缓存却没有关于这条数据的任何记录,而这条数据在缓存中没找到就会向数据库请求获取数据。用户拿不到数据时,就会一直发请求,查询数据库,这样会对数据库的访问造成很大的压力。

如:用户查询一个 id = -1 的商品信息,一般数据库 id 值都是从 1 开始自增,很明显这条信息是不在数据库中,当没有信息返回时,会一直向数据库查询,给当前数据库的造成很大的访问压力。缓存穿透的发生一般是受到 “黑客攻击” 所导致的,所以应该进行监控,如果真的是黑客攻击,及时添加黑名单


解决缓存穿透的方法:

①、缓存空对象从缓存出发,如果当前MySQL数据库不存在的信息,在redis中把它缓存成一个空对象,返回给用户。(代码维护简单,但是效果不是很好)。
②、Redis 也为我们提供了一种解决方案,那就是布隆过滤器(代码维护比较复杂,效果挺好的)。

方法1:缓存空对象

缓存空对象就是指一个请求发送过来,如果此时缓存中和数据库都不存在这个请求所要查询的相关信息,那么数据库就会返回一个空对象,并将这个空对象和请求关联起来存到缓存中,当下次还是这个请求过来的时候,这时缓存就会命中,就直接从缓存中返回这个空对象,这样可以减少访问数据库的压力,提高当前数据库的访问性能。流程如下图所示

 

 但是这会有一个问题:如果大量不存在的请求过来,那么这时候缓存中会缓存许多空对象,如果时间一长,会导致缓存中存在大量空对象,这样不仅会占用许多的内存空间,还会浪费许多资源!我们可以将这些对象在一段时间之后清理,Redis 给我们提供了有关过期时间的命令,这样我们就可以设置空对象的时候顺便设置一个过期时间,就可以解决占用内存空间,浪费资源的问题了!

setex key seconds valule:设置键值对的同时指定过期时间(s)

redisCache.put(Integer.toString(id), null, 60) //过期时间为 60s

方法2:布隆过滤器

布隆过滤器是用来过滤东西的,它是一种基于概率的数据结构,主要判断当前某个元素是否在该集合中,运行速度快。布隆过滤器的巨大用处就是,能够迅速判断一个元素是否在一个集合中。因此他有如下三个使用场景:

  • 网页爬虫对URL的去重,避免爬取相同的URL地址
  • 反垃圾邮件,从数十亿个垃圾邮件列表中判断某邮箱是否垃圾邮箱(同理,垃圾短信)
  • 缓存穿透,将所有可能存在的数据缓存放到布隆过滤器中,当黑客访问不存在的缓存时迅速返回避免缓存及DB挂掉。

布隆过滤器可以简单理解为是一个不怎么精确的 set 结构(set 具有去重的效果)

但是有个小问题是:当使用它的 contains 方法去判断某个对象是否存在时,它可能会误判。也就是说布隆过滤器不是特别精确,但是只要参数设置的合理,它的精确度可以控制的相对足够精确,只会有小小的误判概率。

当布隆过滤器说某个值存在时,这个值可能不存在;当它说不存在时,那就肯定不存在

布隆过滤器特点:

  1. 一个非常大的二进制位数组(数组中只存在 0 和 1)
  2. 拥有若干个哈希函数(Hash Function)
  3. 在空间效率和查询效率都非常高
  4. 布隆过滤器不会提供删除方法,在代码维护上比较困难。

每个布隆过滤器对应到 Redis 的数据结构里面就是一个大型的位数组和几个不一样的无偏hash函数。所谓无偏就是能够把元素的 hash 值算得比较均匀。

向布隆过滤器中添加 key 时,会使用多个 hash 函数对 key 进行 hash 算得一个整数索引值然后对位数组长度进行取模运算得到一个位置,每个 hash 函数都会算得一个不同的位置。再把位数组的这几个位置都置为 1 就完成了 add 操作。( 每一个 key 都通过若干的hash函数映射到一个巨大位数组上,映射成功后,会在把位数组上对应的位置改为1)
那为什么布隆过滤器会存在误判率呢?其实它会误判是如下这个情况:

影响布隆过滤器准确率的三个重要因素:

  • 哈希函数的好坏
  • 存储空间大小
  • 哈希函数个数

如何提高布隆过滤器的准确率呢?

    hash函数的设计也是一个十分重要的问题,对于好的hash函数能大大降低布隆过滤器的误判率。
    对于一个布隆过滤器来说,如果其位数组越大的话,那么每个key通过hash函数映射的位置会变得稀疏许多,不会那么紧凑,有利于提高布隆过滤器的准确率。
    对于一个布隆过滤器来说,如果key通过许多hash函数映射,那么在位数组上就会有许多位置有标志,这样当用户查询的时候,在通过布隆过滤器来找的时候,误判率也会相应降低。
 

2、缓存击穿

造成缓存击穿的原因有两个:

  1. 一个“冷门”key,突然被大量用户请求访问。
  2. 一个“热门”key,在缓存中时间恰好过期,这时有大量用户来进行访问。

这样会导致大并发请求直接穿透缓存,请求数据库,瞬间对数据库的访问压力增大。

 

解决办法:

常用的解决方案是加锁。对于key过期的时候,当key要查询数据库的时候加上一把锁,这时只能让第一个请求进行查询数据库,然后把从数据库中查询到的值存储到缓存中,对于剩下的相同的key,可以直接从缓存中获取即可。

    单机环境下:直接使用常用的锁即可(如:Lock、Synchronized等);
    分布式环境下可以使用分布式锁,如:基于数据库、基于Redis或者zookeeper 的分布式锁。

3、缓存雪崩

缓存雪崩是指在某一个时间段内,缓存集中过期失效,如果这个时间段内有大量请求,而查询数据量巨大,所有的请求都会达到存储层,存储层的调用量会暴增,引起数据库压力过大甚至宕机。

原因:

  • Redis突然宕机
  • 大部分数据失效

举个例子:
比如我们基本上都经历过购物狂欢节,假设商家举办 23:00-24:00 商品打骨折促销活动。程序小哥哥在设计的时候,在 23:00 把商家打骨折的商品放到缓存中,并通过redis的expire设置了过期时间为1小时。这个时间段许多用户访问这些商品信息、购买等等。但是刚好到了24:00点的时候,恰好还有许多用户在访问这些商品,这时候对这些商品的访问都会落到数据库上,导致数据库要抗住巨大的压力,稍有不慎会导致,数据库直接宕机(over)。

当商品没有失效的时候是这样的:

当缓存失效的时候却是这样的:

解决方法:

    redis高可用
    redis有可能挂掉,多增加几台redis实例,(一主多从或者多主多从),这样一台挂掉之后其他的还可以继续工作,其实就是搭建的集群。
    限流降级
    在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量,对某个key只允许一个线程查询数据和写缓存,其他线程等待。
    数据预热
    数据加热的含义就是在正式部署之前,我先把可能的数据先预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中。在即将发生大并发访问前手动触发加载缓存不同的key。
    不同的过期时间
    设置不同的过期时间,让缓存失效的时间点尽量均匀。
 

注参考博客Redis缓存穿透、击穿和雪崩_radis穿刺_野心很大的天蝎的博客-CSDN博客

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

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

相关文章

如何在电力行业运用IPD?

电力行业是国民经济众多垄断行业中较早实施改革的行业之一。近几年我国电力行业保持着较快的发展速度,也取得了很大的成绩,发电机容量和发电量居世界首位。2015-2020年,全国发电量不断攀升。 电力是以电能作为动力的能源。电力的发现和应用掀…

MR300C工业无线WiFi图传模块 内窥镜机器人图像传输有线无线的两种方式

MR300C无线WiFi图传模使用方法工业机器人图像高清传输 ⚫ MR300C图传模块基于MIPS处理器实现,电脑/手机连接模块的WIFI热点或网口即可查看视频流 ⚫ 模块的USB 2.0 Host接口,可接入USB uvc摄像头/内窥镜默认输出的视频格式必须是MJPG ⚫ 模块支持接入摄…

Linux 主函数参数介绍

主函数如下: int main( int argc, char* argv[], char* envp[]) 参数分析如下: (1) argc 参数个数 (2) argv 参数内容,是char*类型,说明传给主函数的内容是一个一个的字符串。 (3) envp 环境变量,传给主函数的也…

蓝牙入耳式耳机老是滑出来,耳朵小适合戴什么样的骨传导耳机

最近体验了几款骨传导耳机,分享下我的使用感受。首先说一下为什么要选择骨传导耳机,我之前是使用入耳式耳机,戴久了耳朵会疼,而且晚上睡觉不能戴。于是就考虑骨传导耳机,因为骨传导耳机在传声的过程中不需要经过耳膜&a…

【Elasticsearch】学好Elasticsearch系列-脚本查询

本文已收录至 Github,推荐阅读 👉 Java 随想录 先看后赞,养成习惯。 点赞收藏,人生辉煌。 文章目录 概念支持的语言Painless特点简单例子 Scripting的CRUDinsert(新增)update(更新)d…

智能工厂:适应不断变化的制造世界

制造业已经从过去传统的装配线工艺流程中走了很长一段路。随着技术的进步和工业 4.0 的兴起,制造业正在迅速发展,以满足现代世界不断变化的需求。近年来出现的一个关键概念就是“智能工厂”。在这篇文章中,我们将探讨什么是智能工厂、它是如何…

为什么要学PMP项目管理?

为什么要学习PMP呢,主要有以下五点: 01提升个人能力 PMP是一个系统学习的过程,充分理解各个项目管理的过程以及项目管理的各个过程组、知识领域等,可以从理论上掌握项目经理应具有的理论素质。能够知道如何对执行的项目进行系统…

【Docker】个人镜像文件Dockerfile制作详解

前言 洁洁的个人主页 我就问你有没有发挥! 知行合一,志存高远。 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是…

jupyter打开ipynb后,还没有运行cell,反复报错

今天遇到了一个比较奇怪的问题: 这个原因是当前目录下有一个code.py的文件,一旦打开ipynb,就是先执行code.py,而且遇到报错,还会反复执行,导致内核崩溃。

Windows 11 家庭中文版找不到组策略文件gpedit.msc

最近因为调整日期问题需要用到组策略文件gpedit.msc,但是发现找不到文件 在按键盘 winR 打开运行界面输入 gpedit.msc 回车 Windows找不到文件’gpedit.msc’。请确定文件名是否正确后,再试-次。 检查电脑Windows系统版本 是 Windows 11 家庭中文版 果断早网上搜…

生信豆芽菜-单基因预后

网址:http://www.sxdyc.com/panCancerPrognosis 该工具主要用于查看单基因在泛癌的预后情况,这里默认用火山图展示 提交后等待运行成功即可,还可以关注公众号:豆芽数据分析

617-合并二叉树

题目: 给你两棵二叉树: root1 和 root2 。 想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果…

How to install GrayLog5.1.2 with one-click script

先决条件: CentOS7.9 OpenSearch2.7 环境下安装 GrayLog5.1 基础环境及组件版本说明 1、CentOS7.9 2、GrayLog5.1.2 3、MongoDB6.0 4、OpenSearch2.8 1. 准备一台 Centos 7.9 主机 最低配置要求 CPU*8 内存16GB HDD500 正式环境根据需要来 2. 一键安装属于…

clickHouse部署

docker仓库地址 https://hub.docker.com/ 1、docker环境搭建 # 1.先安装yml yum install -y yum-utils device-mapper-persistent-data lvm2 # 2.设置阿里云镜像 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo# 3.查…

【C语言】回调函数,qsort排序函数的使用和自己实现,超详解

文章目录 前言一、回调函数是什么二、回调函数的使用1.使用标准库中的qsort函数2.利用qsort函数对结构体数组进行排序 三、实现qsort函数总结 先记录一下访问量突破2000啦,谢谢大家支持!!! 这里是上期指针进阶链接,方便…

季度到季度的组件选择

组件&#xff1a;<template><div class"quarter"><div class"input-wrap" id"closeId" mouseover"handler" click.stop"btn" :style"{color:colorItem}"><i class"el-icon-date"&…

React Native文本添加下划线

import { StyleSheet } from react-nativeconst styles StyleSheet.create({mExchangeCopyText: {fontWeight: bold, color: #1677ff, textDecorationLine: underline} })export default styles

无涯教程-Perl - return函数

描述 此函数在子例程,块或do函数的末尾返回EXPR。 EXPR可以是标量,数组或哈希值&#xff1b;context将在执行时选择。如果没有给出EXPR,则在列表context中返回一个空列表,在标量context中返回undef,在空context中不返回任何内容。 语法 以下是此函数的简单语法- return EXP…

程序设计语言基础知识

1.1程序设计语言的基本概念 1、低级语言与高级语言&#xff1a; 低级语言&#xff1a;汇编语言 高级语言&#xff1a;常见的有Java、C、C、PHP、Python、Delphi等 2、翻译形式&#xff1a;汇编、解释、编译 3、程序设计语言的定义&#xff1a;语法、语义、语用 4、程序设计语言…

汽配企业WMS系统:提升作业效率与过程管控

随着汽配企业竞争的加剧和业务模式的复杂化&#xff0c;许多企业意识到提高仓库作业效率和成本控制能力是企业成功的关键。因此&#xff0c;越来越多的企业选择引入WMS仓储管理系统。然而&#xff0c;汽配企业产品复杂&#xff0c;且从业的人员大部分是老一辈人员&#xff0c;内…