redis之缓存穿透,击透,雪崩~

以下为一个我们正常的缓存流程:

在这里插入图片描述

缓存雪崩:

在双十一的时候,淘宝的首页访问量是非常大的,所以它的很多数据是放在redis缓存里面,对应redis中的key,假设设置了缓存失效的时间为3小时,超过这三个小时后,在一瞬间redis缓存key大量失效,导致所有的请求都要直接和数据库交互,就会导致数据库响应不及时挂掉,此时首页就没办法向外界提供服务了,这就是缓存雪崩

在这里插入图片描述

缓存雪崩解决方案:

1:设置缓存的失效时间,在初始化的时候,我们可以随机初始化它的失效时间,不要让他们都在同一时间失效

2:设置过期标志更新缓存,记录缓存数据是否过期(设置提前量),如果过期会触发通知另外的线程在后台去更新实际key的缓存。

3:构建多级缓存架构:nginx缓存+redis缓存+其他缓存等

缓存穿透:

在这里插入图片描述

缓存穿透解决方案:

1:如果这个请求穿透redis直接到数据库,那么数据库无论查询到什么样的结果,都将结果缓存到redis中去,那么等下次,它使用同样的恶意数据,就不会穿透redis,但如果这个老六换了不同的参数,该解决办法就失效了

2:将这个老六的ip拉黑,但这个老六也可能换不同的ip

3:对参数的合法性检验,在判断这个参数不合法的时候就直接return

4:使用布隆过滤器(推荐!),下文有讲述

缓存击穿:

商品的秒杀,在秒杀之前程序员会将该商品的数据放到redis缓存中,对应redis中的一个key,假设设置key的过期时间为4个小时,但直到4个半小时,秒杀依然没有结束,而此时该商品的key缓存突然失效了,导致大量的请求在redis缓存中查询不到数据,那么就会直接访问数据库,从而导致数据库响应不及时而挂掉,该过程就叫缓存击穿

在这里插入图片描述

缓存击穿解决方案:

1:预先设置热门数据:在redis高峰访问之前,把一些热门的数据提前存入到redis里面,加大这些热门数据key的时长。

2:实时调整:现场监控那些数据热门,实时调整key的过期时间。

3:让数据对应的key永远不过期

4:使用分布式锁,单体应用使用互斥锁

布隆过滤器:

它其实就是一个很长的二进制向量,如下所示:

在这里插入图片描述

布隆过滤器的作用就是判断一个数据存不存在这个数组里面,如果不存在就是0,存在就是1

在这里插入图片描述

它是由一串二进制数组组成的数据,所以它占据的空间是非常小的,它插入和查询的操作是非常快的,因为它是计算这个数据的哈希值,再由哈希值映射到这个数组的下标,只需要根据算好的下标找对应的值即可,所以它的时间复杂度为O(K),之所以是O(K)不是O(1),是因为哈希函数的个数是不确定的,并且由于过滤器本身的数据就是二进制只有数字0和1,不存储原始数据,那么就使得保密性非常好。

但它也存在着许多的缺点,如下所示,布隆过滤器很难完成删除工作

假设有两个数据,“你好”和“hello”,经过哈希值运算,最终都被存储在下标为2的位置,那么我们仅根据下标就无法判断到底存储的是那个数据

在这里插入图片描述

假设此时我们要删除“hello”这个数据,经过一系列运算,算出它在下标为2的这个位置,那么将下标2位置的这个1改成0,就代表已经删除这个数据了,但是由于“你好”这个数据也存储在这里啊,所以删除“hello”的同时把“你好”也删除了,就会造成数据的误删

此外,它还有一个最大的缺点,它很容易进行误判,因为不同数据计算出来的哈希值可能是相同的,所以存在相同的哈希值,就会存在误判的情况,如下所示:

假设当前下标位2的位置只存储了数据“你好”,此时数据“hello”经过计算也需要存储在下标为2的位置,但判断过后,发现这里已经有数据了,那么就会误判数据“hello”已经存在了

在这里插入图片描述

而上述的这种误判几乎是解决不了的问题,只能减少误判的概率,那么我们怎么去减少误判的概率呢?

如下所示,我们使用Java实现布隆过滤器,我这里使用的是guava是由谷歌公司提供的工具包,里面提供了布隆过滤器的实现。

第一步:导入对应的依赖

 <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>30.1.1-jre</version>
 </dependency>

第二步:编写测试类:

package org.example;

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;

import java.nio.charset.StandardCharsets;

public class bulong {
    public static void main(String[] args) {
        // 初始化布隆过滤器,设计预计元素数量为1000000L,误差率为3%
        BloomFilter<CharSequence> bloomFilter = BloomFilter.create(Funnels.stringFunnel(StandardCharsets.UTF8), 100_0000, 0.03);
        int n = 1000000;
        for (int i = 0; i < n; i++) {
            bloomFilter.put(String.valueOf(i));
        }
        int count = 0;
        for (int i = 0; i < (n * 2); i++) {
            if (bloomFilter.mightContain(String.valueOf(i))) {
                count++;
            }
        }
        System.out.println("过滤器误判率:" + 1.0 * (count - n) / n);
    }
}

在这里插入图片描述

将误判率设置为0.01

 BloomFilter<CharSequence> bloomFilter = BloomFilter.create(Funnels.stringFunnel(StandardCharsets.UTF_8), 1000000, 0.01);

输出如下所示:

在这里插入图片描述

我们所设置的误判率是能影响最终的误判结果的,误判率设置的越低计算所需的时间会越久所需要的空间量就越大所需的哈希函数就越多,原因对同一个数据使用多个不同的哈希函数所得到的哈希值相同的概率就越低那么它们不同的数据存储在相同的位置的概率就越低误判的概率就越低,但是由于哈希函数增多了,就会导致计算出的哈希值增多,进而导致二进制数据增多,所以也会占用更多的空间

布隆过滤器解决缓存穿透问题:

我们可以将布隆过滤器理解为一个黑名单或者白名单,因为它的主要作用就是判断这个元素存不存在这个白名单或者黑名单里面,

布隆过滤器白名单:

在这里插入图片描述

布隆过滤器黑名单:

在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Hadoop_02】Hadoop运行模式

1、Hadoop的scp与rsync命令&#xff08;1&#xff09;本地运行模式&#xff08;2&#xff09;完全分布式搭建【1】利用102将102的文件推到103【2】利用103将102的文件拉到103【3】利用103将102的文件拉到104 &#xff08;3&#xff09;rsync命令&#xff08;4&#xff09;xsync…

smarty模版 [BJDCTF2020]The mystery of ip 1

打开题目 点击flag给了我们一个ip 点击hint&#xff0c;查看源代码处告诉了我们要利用这个ip bp抓包&#xff0c;并添加X-Forward-For头 所以这道题是XFF可控 本来联想到XFF漏洞引起的sql注入&#xff0c;但是我们无论输入什么都会正常回显&#xff0c;就联想到ssti注入 我们…

前端开发_移动Web+动画

平面转换 作用&#xff1a;为元素添加动态效果&#xff0c;一般与过渡配合使用 概念&#xff1a;改变盒子在平面内的形态&#xff08;位移、旋转、缩放、倾斜&#xff09; 平面转换又叫 2D 转换 平移 属性&#xff1a;transform: translate(X轴移动距离&#xff0c;Y轴移动…

研习代码 day52 | 单调栈问题——柱状图中最大的矩形

一、柱状图中最大的矩形 1.1 题目 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: 输入&#xff1a;heights [2,1,5,6,2,3] 输出&#xff1a;…

获取类class对象的方式

一、什么是class对象 Class类位于java核心包lang包中&#xff0c;它是反射的源头。Class对象用于记录每个类的运行时数据结构&#xff0c;或者说是在内存中访问类的静态数据的接口&#xff0c;每个类都有一个唯一的Class对象。Class对象不能直接通过new来获取&#xff0c;因为…

Bomb Lab环境配置及解题

Bomb Lab环境配置及解题 前言&#xff1a; 自上次做Lab隔了不少时间&#xff0c;环境配置也有点忘了&#xff0c;上次用的是mac搭docker这次直接用windows虚拟机&#xff0c;很简单&#xff0c;打开虚拟机用命令安装一下gdb和wget&#xff0c;然后用wget把官网的实验材料下载…

tomcat源码学习记录

tomcat 学习记录 tomcat 编译ant 下载编译运行 源码Debug运行 Bootstrap运行Tomcat查看状态 pom.xml测试EmbeddedTomcat 参考书籍博客 tomcat 编译 下载 tomcat 10 源码&#xff0c;解压然后idea导入 包存放的默认位置如下&#xff1a;base.path${user.home}/tomcat-build-lib…

【操作系统笔记】-文件系统

引言 之前已经学习过数据在内存中是如何表示&#xff0c;如何存储&#xff0c;但是这些存储在PC断电后数据便消失。因此我们需要一个可以持久化存储并且容量远远大于内存的结构&#xff0c;这一篇我们将学习&#xff0c;文件是如何被组织和操作的&#xff0c;这是一个操作系统…

VS2009和VS2022的错误列表可复制粘贴为表格

在VS2019或VS2022中&#xff0c;可看到如下错误列表&#xff1a; 如果复制这两行错误信息&#xff1a; 然后把它粘贴到word文件&#xff0c;就可以看到以下表格&#xff1a; 严重性 代码 说明 项目 文件 行 禁止显示状态 错误(活动) E0020 未定义标识符 "dd"…

爱智EdgerOS之深入解析AI图像引擎如何实现AI视觉开发

一、前言 AI 视觉是为了让计算机利用摄像机来替代人眼对目标进行识别&#xff0c;跟踪并进一步完成一些更加复杂的图像处理。这一领域的学术研究已经存在了很长时间&#xff0c;但直到 20 世纪 70 年代后期&#xff0c;当计算机的性能提高到足以处理图片这样大规模的数据时&am…

有源滤波装置在水处理行业配电系统中的应用

摘要&#xff1a;在水处理行业供配电系统中&#xff0c;涉及曝气风机、提升泵、污泥脱水设备等负荷设备&#xff0c;导致异步电动机产生较多无功功率和大量的谐波&#xff0c;使系统功率因数下降&#xff0c;以及谐波对配电系统、负载产生较大的危害。就此&#xff0c;水处理行…

53. Protocol buffer 的Go使用

文章目录 一、介绍二、安装三、protoc3语法1、 protoc3 与 protoc2区别2、proto3生成go代码包Message内嵌Message字段单一标量字段单一message字段可重复字段slicemap字段枚举 一、介绍 Protobuf是Google旗下的一款平台无关&#xff0c;语言无关&#xff0c;可扩展的序列化结构…

time模块(python)

一.sleep休眠 [rootrhel8 day04]# vim demo01_time.py import time def banzhuan():print("搬砖")time.sleep(3.5) #让程序休眠3.5秒print("结束")banzhuan()[rootrhel8 day04]# python3 demo01_time.py 搬砖 结束运行时&#xff0c;会发现程序中间暂停…

征途漫漫:汽车MCU的国产替代往事

01.西雁东飞&#xff0c;南下创业 1985年&#xff0c;山东大学物理系毕业的周生明加入878厂&#xff08;“北霸天”&#xff09;参与MOS电路研发&#xff0c;随后几年&#xff0c;大洋彼岸的英特尔相继推出CPU 386\486、奔腾系列等产品。在摩尔定律的凸显、进口和走私的剧烈冲…

js/jQuery常见操作 之各种语法例子(包括jQuery中常见的与索引相关的选择器)

js/jQuery常见操作 之各种语法例子&#xff08;包括jQuery中常见的与索引相关的选择器&#xff09; 1. 操作table常见的1.1 动态给table添加title&#xff08;指定td&#xff09;1.1.1 给td动态添加title&#xff08;含&#xff1a;获取tr的第几个td&#xff09;1.1.2 动态加工…

RocketMQ-RocketMQ高性能核心原理(流程图)

1.NamesrvStartup 2.BrokerStartup 3. DefualtMQProducer 4.DefaultMQPushConsumer

Unity-Shader - 2DSprite描边效果

实现一个简单的2D精灵图描边效果&#xff0c;效果如下 实现思路&#xff1a; 可以通过判断该像素周围是否有透明度为 0的值&#xff0c;如果有&#xff0c;则说明该像素位于边缘。 所以我们需要打开alpha blend&#xff0c;即&#xff1a; Blend SrcAlpha OneMinusSrcAlpha&am…

Java 11 到 Java 21:无缝迁移的可视化指南

迁移到 Java 21 的理由 在我们探索从 Java 11 迁移到 Java 21 的必要性的旅程中&#xff0c;我们深入研究了四个关键类别&#xff0c;并强调了这一转变的重要性。每个方面都至关重要&#xff0c;共同为采用最新版本的 Java 编程语言打造了一个引人注目的案例。 1. 安全性&#…

【数据结构(九)】线索化二叉树(3)

文章目录 1. 前言——问题引出2. 线索二叉树的基本介绍3. 线索二叉树的应用案例3.1. 思路分析3.2. 代码实现 4. 遍历线索化二叉树4.1. 代码实现 1. 前言——问题引出 问题&#xff1a;     将数列 {1, 3, 6, 8, 10, 14 } 构建成一颗二叉树. &#xff08;n17个空指针域&…