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

news2024/11/18 15:39:00

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

在这里插入图片描述

缓存雪崩:

在双十一的时候,淘宝的首页访问量是非常大的,所以它的很多数据是放在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);

输出如下所示:

在这里插入图片描述

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

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

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

布隆过滤器白名单:

在这里插入图片描述

布隆过滤器黑名单:

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

视觉学习笔记12——百度飞浆框架的PaddleOCR 安装、标注、训练以及测试

系列文章目录 虚拟环境部署 参考博客1 参考博客2 参考博客3 参考博客4 文章目录 系列文章目录一、简单介绍1.OCR介绍2.PaddleOCR介绍 二、安装1.anaconda基础环境1&#xff09;anaconda的基本操作2&#xff09;搭建飞浆的基础环境 2.安装paddlepaddle-gpu版本1&#xff09;安装…

区块链实验室(29) - 关闭或删除FISCO日志

1. FISCO日志 缺省情况下&#xff0c;FISCO启动日志模块&#xff0c;日志记录的位置在节点目录中。以FISCO自带案例为例&#xff0c;4节点的FISCO网络&#xff0c;24个区块产生的日志大小&#xff0c;见下图所示。 2.关闭日志模块 当节点数量增大&#xff0c;区块高度增大时&…

利用Wix打包安装包

利用Wix打包安装包 背景具体步骤1、安装 WiX Toolset 工具集2、安装 WiX Toolset 系列 Visual Studio 插件3、创建Wix工程4、添加工程文件5、修改Product元素6、修改Package元素7、修改MajorUpgrade元素8、修改Media属性9、设置安装引导界面10、添加WPF项目文件11、添加桌面快捷…

资源三号卫星数字表面模型库

资源三号卫星数字表面模型库&#xff08;简称ChinaDSM-China Digital Surface Model&#xff09;是以资源三号卫星立体影像为数据源&#xff0c;采用自主知识产权的基于多基线、多匹配特征的地形信息自动提取技术&#xff0c;快速处理和生产提取的高精度、高保真15米格网数字表…

排序算法之四:直接选择排序

1.基本思想 每一次从待排序的数据元素中选出最小&#xff08;或最大&#xff09;的一个元素&#xff0c;存放在序列的起始位置&#xff0c;直到全部待排序的数据元素排完 。 2.直接选择排序 在元素集合array[i]--array[n-1]中选择关键码最大(小)的数据元素 若它不是这组元素中的…

第 119 场 LeetCode 双周赛题解

A 找到两个数组中的公共元素 模拟 class Solution { public:vector<int> findIntersectionValues(vector<int> &nums1, vector<int> &nums2) {unordered_set<int> s1(nums1.begin(), nums1.end()), s2(nums2.begin(), nums2.end());vector<…

keepalived+lvs 对nginx做负载均衡和高可用

LVS_Director KeepAlivedKeepAlived在该项目中的功能&#xff1a; 1. 管理IPVS的路由表&#xff08;包括对RealServer做健康检查&#xff09; 2. 实现调度器的HA http://www.keepalived.orgKeepalived所执行的外部脚本命令建议使用绝对路径实施步骤&#xff1a; 1. 主/备调度器…

《深入浅出进阶篇》洛谷P3197 越狱——集合

洛谷P3197 越狱 题目大意&#xff1a; 监狱有 n 个房间&#xff0c;每个房间关押一个犯人&#xff0c;有 m 种宗教&#xff0c;每个犯人会信仰其中一种。如果相邻房间的犯人的宗教相同&#xff0c;就可能发生越狱&#xff0c;求有多少种状态可能发生越狱。 答案对100,003 取模。…

Python 网络爬虫(三):XPath 基础知识

《Python入门核心技术》专栏总目录・点这里 文章目录 1. XPath简介2. XPath语法2.1 选择节点2.2 路径分隔符2.3 谓语2.4 节点关系2.5 运算符3. 节点3.1 元素节点(Element Node)3.2 属性节点(Attribute Node)

MongoDB——基本概念+docker部署+基本命令

1.MongoDB相关概念 业务应用场景 MongoDB简介 BSON二进制的JSON 数据类型 MongDB的特点 2.单机部署 windows上的安装启动 windows版本的直接去官网下载即可&#xff0c;这里的安装运行我试了一次没有成功。干脆不用了&#xff0c;反正以后也不会在windows系统上用的这个 li…

NSSCTF第15页(1)

[CISCN 2019华东南]Web4 点击read something&#xff0c;发现访问了百度 读到了源码 就是ssrfflask import re, random, uuid, urllib from flask import Flask, session, requestapp Flask(__name__) random.seed(uuid.getnode()) app.config[SECRET_KEY] str(random.rando…

JSON字符串转泛型对象

JSON字符串转泛型对象 以下问题只仅限于博主自身遇到&#xff0c;不代表绝对出现问题 相关类展示&#xff1a; 参数基类 public class BaseParams { }基类 public abstract class AbstractPush<Params extends BaseParams> {protected abstract void execute(Params…

Shell数组函数:数组——数组和循环(四)

使用数组统计&#xff0c;用户shell的类型和数量 一、脚本编辑 [root192 ~]# vim shell.sh #!/bin/bash declare -A shells while read ii dotypeecho $ii | awk -F: {print $7}let shells[$type] done < /etc/passwdfor i in ${!shells[]} doecho "$i: ${shells[$i]…

开源电子合同签署平台小程序源码/电子文件签字+在线合同签署系统源码/电子合同小程序源码

源码简介&#xff1a; 开源电子合同签署平台小程序源码&#xff0c;它是电子文件签字在线合同签署系统源码/电子合同小程序源码 目前商业端和开源端一致&#xff0c;免费开源状态&#xff01; 聚合市场上各类电子合同解决方案商&#xff0c;你无需一个一个的对接电子合同厂商…

<JavaEE> 经典设计模式之 -- 线程池

目录 一、线程池的概念 二、Java 标准库中的线程池类 2.1 ThreadPoolExecutor 类 2.1.1 corePoolSize 和 maximumPoolSize 2.1.2 keepAliveTime 和 unit 2.1.3 workQueue 2.1.4 threadFactory 2.1.5 handler 2.1.6 创建一个参数自定义的线程池 2.2 Executors 类 2.3…

前端开发_移动Web+动画

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

vue2 cron表达式组件

vue2 cron表达式组件 1. 先上图 2. 代码目录 3. 直接上代码 &#xff08;组件代码太多&#xff0c;直接上压缩包&#xff0c;解压后直接用&#xff0c;压缩包再博客顶部&#xff09; 4. 使用注&#xff1a;示例代码中使用了element-ui // HomeView.vue<template><…

Python如何实现性能自动化测试

一、思考 1.什么是性能自动化测试? 性能 系统负载能力超负荷运行下的稳定性系统瓶颈 自动化测试 使用程序代替手工提升测试效率 性能自动化 使用代码模拟大批量用户让用户并发请求多页面多用户并发请求采集参数&#xff0c;统计系统负载能力生成报告 2.Python中的性能…

多任务学习(Multi-Task Learning)和迁移学习(Transfer Learning)的详细解释以及区别(系列1)

文章目录 前言一、多任务学习&#xff08;Multi-Task Learning&#xff09;是什么&#xff1f;二、多任务学习&#xff08;Multi-Task Learning&#xff09;对数据的要求三、迁移学习是什么&#xff1f;四&#xff0c;迁移学习对数据的要求五&#xff0c;多任务学习与迁移学习的…

LeetCode Hot100 22.括号生成

题目&#xff1a; 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 方法&#xff1a;灵神 组合型回溯-剪枝-枚举填左括号还是右括号 代码&#xff1a; class Solution {private int n;private char[] pat…