Redis:缓存击穿,缓存穿透,缓存雪崩

devtools/2024/9/20 4:05:24/ 标签: 缓存, redis, 数据库

缓存穿透

缓存数据库中都没有的数据,可用户还是源源不断的发起请求,导致每次请求都会到数据库,从而压垮数据库

这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。

*** 解决方案**

  • 对空值进行缓存标志
    • 对于不存在的数据,同样设置一个特殊的 Value 到缓存中,并设置过期时间
  • 使用布隆过滤器
    • 如果布隆过滤器认为值不存在,那么值一定是不存在的,无需查询缓存也无需查询数据库
    • 对于极小概率的误判请求,才会最终让非法 Key 的请求走到缓存数据库
  • 业务层校验
    • 用户发过来的请求,根据请求参数进行校验,对于明显错误的参数,直接拦截返回。

缓存雪崩

缓存雪崩是指当缓存中有大量的key在同一时刻过期,或者Redis直接宕机了,导致大量的查询请求全部到达数据库,造成数据库查询压力骤增,甚至直接挂掉。

​ 和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库

*** 现象 ** :数据库的访问压力瞬间激增,服务负载过高

产生雪崩的原因大致有两种

  • 缓存系统不可用
  • 大量的key在同一时间失效,导致大量数据回源

解决方案

  • 1、差异化缓存过期时间

    • 避免缓存设置相近的有效期,我们可以在设置有效期时增加随机值;
  • 2、缓存永不过期,后台线程刷新

    • 初始化缓存数据的时候设置缓存永不过期,然后启动一个后台线程 30 秒一次定时把所有数据更新到缓存,而且通过适当的休眠,控制从数据库更新数据的频率,降低数据库压力
  • 3、增强redis的高可用性

    • 构建 Redis 缓存高可靠集群

缓存击穿

在某些 Key 属于极端热点数据,且并发量很大的情况下,如果这个 Key 过期,可能会在某个瞬间出现大量的并发请求同时回源,相当于大量的并发请求直接打到了数据库。这种情况,就是我们常说的缓存击穿或缓存并发问题。

*** 现象 ** :数据库的访问压力瞬间激增,Redis正常运行

*** 解决办法**

  • 业务允许下,设置缓存永不过期

    • 启动一个后台线程 30 秒一次定时把所有数据更新到缓存,而且通过适当的休眠,控制从数据库更新数据的频率,降低数据库压力
  • 使用互斥锁

    • 缓存失效的时候(判断拿出来的值为空),不是立即去加载数据库
    • 先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX)去set一个mutex key。
    • 当操作返回成功时,再进行加载数据库的操作,并回设缓存,最后删除mutex key。
    • 当操作返回失败,证明有线程在加载数据库,当前线程睡眠一段时间再重试整个get缓存的方法。

@Autowiredprivate RedissonClient redissonClient;@GetMapping("mutex")public String mutex() {String data = stringRedisTemplate.opsForValue().get("hot_key");if (StringUtils.isEmpty(data)) {RLock locker = redissonClient.getLock("mutex_locker");//获取分布式锁if (locker.tryLock()) {try {data = stringRedisTemplate.opsForValue().get("hot_key");//双重检查,因为可能已经有一个B线程过了第一次判断,在等锁,然后A线程已经把数据写入了Redis中if (StringUtils.isEmpty(data)) {//回源到数据库查询data = getDatabaseData();stringRedisTemplate.opsForValue().set("hot_key", data, 5, TimeUnit.SECONDS);}} finally {//别忘记释放,另外注意写法,获取锁后整段代码try+finally,确保unlock万无一失locker.unlock();}}}return data;}

缓存穿透和缓存击穿的区别:


http://www.ppmy.cn/devtools/96906.html

相关文章

应急响应:挖矿木马-实战 案例一.【Linux 系统-排查和删除】

什么是挖矿木马 挖矿木马是一种恶意软件,它在未经用户许可的情况下,利用用户的计算资源来挖掘加密货币,从而为攻击者带来非法收益。这类软件通常通过多种手段传播,例如利用系统漏洞、弱密码爆破、伪装正常软件等方法感染目标设备…

【CTF | WEB】003、攻防世界WEB题目之xff_referer

文章目录 xff_referer题目描述:解题思路:XFF与Referer基本了解1. XFF(X-Forwarded-For):2. Referer:简单总结: 解题实操: xff_referer 题目描述: X老师告诉小宁其实xff和referer是可以伪造的。…

Springboot-从服务器获取一个输入流,转成视频文件存到oss

要在Spring Boot应用中从服务器获取一个输入流,然后将该流转换为视频文件并存储到阿里云 OSS中,你可以遵循以下步骤: 设置阿里云OSS客户端:首先,你需要配置阿里云OSS客户端,以便能够上传文件到OSS。 获取输入流:使用HTTP客户端(如RestTemplate或WebClient)从服务器…

c语言通过逻辑运算符和if语句制作招聘筛选程序

c语言里逻辑运算符 && 逻辑与 a&&b || 逻辑或 a||b ! 逻辑非 逻辑运算符计算结果是true和false,其中用1表示true,0表示false 这里要制作一个招聘筛选程序&#xff0c;要求年龄大于等于25&#xff0c;身高不低于1米7 代码如下 #include<s…

4.4、配置交换机vlan

一、配置前的碎碎恋 前面大致了解了二层交换机的一些缺点&#xff0c;还有什么是vlan&#xff0c;不同vlan之间的通信。 接下来看看配置交换机vlan用到哪些命令&#xff1a; 1.进入全局配置模式 Switch> enable Switch# configure terminal Switch(config)# 2. 创建VLAN…

结合GPT与Python实现端口检测工具(含多线程)

端口检测器是一个非常实用的网络工具&#xff0c;它主要用于检测服务器或本地计算机上的特定端口是否处于开放状态。通过这个工具&#xff0c;你可以快速识别和诊断网络连接问题&#xff0c;确保关键服务的端口能够正常接收和处理数据。这对于网络管理员和开发者来说是一个不可…

【PGCCC】使用 Postgres 递归 CTE 进行图形检索

您是否知道可以将 Postgres 用作某些用例的图形数据库&#xff1f; 假设您有如下图表&#xff1a; 我们可以在 NetworkX 中构建此图&#xff1a; 1import networkx as nx23G nx.Graph()45G.add_edges_from([6 ("A", "B"),7 ("A", "…

Windows 环境下 Go 语言使用第三方压缩包 gozstd 的报错处理

该文章主要记录在windows平台用go语言使用gozstd包时&#xff0c;遇到的错误及处理过程&#xff08;踩坑之旅&#xff09;&#xff01; 一、gozstd简介 gozstd是一个针对Zstandard&#xff08;简称Zstd&#xff09;的Go语言包装器&#xff0c;它提供了简单且高效的API&#xf…

从0开发一个 组件/插件 并部署

从零开始发布一个 Vue3 Vite 的 npm 包 1. npm账号配置 1.1 注册新账号 注册地址&#xff1a; www.npmjs.com/signup 1.2 登录账号 在命令行输入&#xff1a; npm login&#xff0c;此时会提醒你打开浏览器进行登录&#xff0c;然后邮件接收验证码&#xff0c;输入登录 …

在PHP中使用file_get_contents提取JSON值

在PHP开发中&#xff0c;我们经常需要处理各种数据格式&#xff0c;其中JSON是一种非常常见的数据交换格式。有时候&#xff0c;我们需要从网络上的某个URL获取JSON格式的数据&#xff0c;并提取其中的值。本文将介绍如何使用file_get_contents函数在PHP中获取并解析JSON数据。…

MT6761 快充同步

MT6761 是反激式电源的高性能60V同步整流器。MT6761兼容各种反激转换器类型。支持 DCM、CCM 和准谐振模式。MT6761集成了一个60V功率MOSFET&#xff0c;可以取代肖特基二极管&#xff0c;提高效率。V SW <V TH-ON 时&#xff0c;MT6761内部 MOSFET 导通。V SW >V TH-OFF …

贪心算法3

134. 加油站 全局思考&#xff1a;总油量减去总消耗大于等于零那么一定可以跑完一圈,局部贪心&#xff1a;累加每个站的净胜油量,如果<0,则在此之前(包括该站)都不是起始位置,从下一个位置开始寻找 class Solution { public:int canCompleteCircuit(vector<int>&…

k8s 存储卷管理 持久卷 pv/pvc 临时卷

持久卷 hostPath 卷 NFS 卷 访问验证 nfs 卷 curl http://10.244.1.19 PV/PVC 持久卷声明 临时卷 configMap nginx 解析 php 创建 ConfigMap 挂载 ConfigMap secret 卷 emptyDir 卷

三菱定位控制(一)

下面小编开始开始总结学习定位控制&#xff0c;以Q系列三菱PLC来展开学习&#xff0c;希望对读者或者小白有所帮助&#xff01;&#xff01;&#xff01; 一 三菱PLC定位模块 为什么需要学习定位模块&#xff08;三菱FXCPU能实现一个伺服电机的控制&#xff0c;多个要买定位模…

vue3中子向父传数据

父组件 首先&#xff0c;我们创建一个父组件&#xff0c;名为 ParentComponent.vue&#xff1a; <template><div><h1>父组件</h1><p>从子组件接收到的数据&#xff1a;{{ receivedData }}</p><ChildComponent sendData"updateDa…

手写qiankun-页面渲染

registerMicroApps配置子应用 start读取配置&#xff0c;拉取子应用并完成渲染 //全局变量 let _app [];//更好的获取全局变量_app export const getApps () > _app;//app为传递过来的子应用数组 export const registerMicroApps (app) > {_app app; };export cons…

【nacos 第二篇章】动手实践(从零代码开发版)

一、环境准备 本章将通过手把手的教程一步一步教你如何从零开发一个微服务应用。 首先需要安装好 nacos 服务并启动。安装 nacos 服务请看作者的 【nacos 第一篇章】安装一下 nacos 文章。 二、初始化项目 如上图所示&#xff0c;可以建立一个基础的项目。 搭建了基础项目之…

MySQL面试问题(二)

MySQL面试问题&#xff08;二&#xff09; 文章目录 MySQL面试问题&#xff08;二&#xff09;为什么要使用索引索引是不是越多越好MySQL索引机制什么是聚簇索引没有主键innodb如何处理联合索引批量向MySQL中导入1000w数据如何优化分页时偏移量很大效率很差如何优化大数据量高并…

AI数字员工技能全开,招生、培训、写教案,样样都行

只需要几个AI数字员工&#xff0c;就可以协助您办一所高质量的学校。 教务管理、教师培训、招生咨询、家校沟通、学生评价、资料整理、学习伴侣、写教案、总结、学生评语等。 这些都可以用AI数字员工来完成。 比如&#xff0c;AI培训专员给教师做制度培训、教学培训&#xf…

模拟实现简单vector

vector作为STL成员之一&#xff0c;在实际中也使用广泛。所有了解实现一个简单的vector也有助于我们更好的认识vector及其底层实现。 #pragma once #include<iostream> #include<assert.h> using namespace std;namespace cls {template<class T>class vecto…