redis缓存穿透、缓存击穿、缓存雪崩及其解决方法

缓存穿透、缓存击穿、缓存雪崩是redis的三大问题。
在介绍这三大问题之前,我们需要先了解Redis作为一个缓存中间件,在项目中是如何工作的。首先看一下在没有缓存中间件的时候的系统数据访问的架构图:
在这里插入图片描述
客户端发起一个查询请求的时候,首先去缓存中查询,如果数据在缓存中存在,则直接将缓存中的数据返回给客户端;如果数据在缓存中不存在,则继续查询数据库,如果数据在数据库中存在,则将该数据放入缓存中,并返回给客户端,如果数据在数据库中也不存在,则直接返回null给客户端。

什么是缓存穿透
缓存穿透是指查询一个缓存中和数据库中都不存在的数据,导致每次查询这条数据都会透过缓存,直接查库,最后返回空。当用户使用这条不存在的数据疯狂发起查询请求的时候,对数据库造成的压力就非常大,甚至可能直接挂掉。这种情况的流程就变成下图这样了:在这里插入图片描述
缓存穿透解决方案
解决缓存穿透的方法一般有两种,第一种是缓存空对象,第二种是使用布隆过滤器。

第一种方法比较好理解,就是当数据库中查不到数据的时候,我缓存一个空对象,然后给这个空对象的缓存设置一个过期时间,这样下次再查询该数据的时候,就可以直接从缓存中拿到,从而达到了减小数据库压力的目的。但这种解决方式有两个缺点:(1)需要缓存层提供更多的内存空间来缓存这些空对象,当这种空对象很多的时候,就会浪费更多的内存;(2)会导致缓存层和存储层的数据不一致,即使在缓存空对象时给它设置了一个很短的过期时间,那也会导致这一段时间内的数据不一致问题。

第二种方案是使用布隆过滤器,这是比较推荐的方法。所谓布隆过滤器,就是一种数据结构,它是由一个长度为m bit的位数组与n个hash函数组成的数据结构,位数组中每个元素的初始值都是0。在初始化布隆过滤器时,会先将所有key进行n次hash运算,这样就可以得到n个位置,然后将这n个位置上的元素改为1。这样,就相当于把所有的key保存到了布隆过滤器中了。

举个例子,比如我们一共有3个key,我们对这3个key分别进行3次hash运算,key1经过三次hash运算后的结果分别为2/6/10,那么就把布隆过滤器中下标为2/6/10的元素值更新为1,然后再分别对key2和key3做同样操作,结果如下图:
在这里插入图片描述
这样,当客户端查询时,也对查询的key做3次hash运算得到3个位置,然后看布隆过滤器中对应位置元素的值是否为1,如果所有对应位置元素的值都为1,就证明key在库中存在,则继续向下查询;如果3个位置中有任意一个位置的值不为1,那么就证明key在库中不存在,直接返回客户端空即可。如下图:
在这里插入图片描述
当客户端查询key4时,key4的3次hash运算中,有一个位置8的值为0,就说明key4在库中不存在,直接返回客户端空即可。

所以,布隆过滤器就相当于一个位于客户端与缓存层中间的拦截器一样,负责判断key是否在集合中存在。如下图:
在这里插入图片描述
布隆过滤器的好处就是解决了第一种缓存空值的不足,但布隆过滤器也存在缺陷,首先,它有误判的可能,比如在上面客户端查询key4的图中,假如key4经过3次hash运算得到的位置分别是2/4/6,由于这3个位置的值都是1,所以,布隆过滤器就认为key4在库中存在,进而继续向下查询了。所以,布隆过滤器判断存在的key实际上可能是不存在的,但布隆过滤器判断不存在的key是一定不存在的。它的第二个缺点就是删除元素比较难,比如现在要删除key2这个元素,那么需要将2/7/11三个位置的元素值改为0,但这样就会影响到key1和key3的判断。
什么是缓存击穿
缓存击穿是指当缓存中某个热点数据过期了,在该热点数据重新载入缓存之前,有大量的查询请求穿过缓存,直接查询数据库。这种情况会导致数据库压力瞬间骤增,造成大量请求阻塞,甚至直接挂掉。在这里插入图片描述
缓存击穿解决方案
解决缓存击穿的方法也有两种,第一种是设置key永不过期;第二种是使用分布式锁,保证同一时刻只能有一个查询请求重新加载热点数据到缓存中,这样,其他的线程只需等待该线程运行完毕,即可重新从Redis中获取数据。

第一种方式比较简单,在设置热点key的时候,不给key设置过期时间即可。不过还有另外一种方式也可以达到key不过期的目的,就是正常给key设置过期时间,不过在后台同时启一个定时任务去定时地更新这个缓存。
在这里插入图片描述
第二种方式使用了加锁的方式,锁的对象就是key,这样,当大量查询同一个key的请求并发进来时,只能有一个请求获取到锁,然后获取到锁的线程查询数据库,然后将结果放入到缓存中,然后释放锁,此时,其他处于锁等待的请求即可继续执行,由于此时缓存中已经有了数据,所以直接从缓存中获取到数据返回,并不会查询数据库。

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

在这里插入图片描述
缓存雪崩解决方案
针对第一种大量key同时过期的情况,解决起来比较简单,只需要将每个key的过期时间打散即可,使它们的失效点尽可能均匀分布。
针对第二种redis发生故障的情况,部署redis时可以使用redis的几种高可用方案部署,部署方法可以主从(masterslave)架构、哨兵(sentinel)、Redis集群(Redis Cluster)。
除了上面两种解决方式,还可以使用其他策略,比如设置key永不过期、加分布式锁等。

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

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

相关文章

Maya 2024 for Mac/Win:重塑三维创意世界的利器

在数字化浪潮汹涌的当下,三维图形软件早已成为创意产业不可或缺的重要工具。而在这其中,Maya 2024以其卓越的性能和丰富的功能,赢得了无数设计师的青睐。无论是Mac还是Win平台,Maya 2024都能为您的三维创作提供强大的支持。 Maya…

【ssh免密设置】

本机远程的服务器上执行: ssh-keygen -t rsa2.然后修改公钥的权限(xxxxx.pub需要替换) chmod 600 xxxxx.pub3.再执行命令,将公钥导到免密的服务器上(服务器ip地址替换成自己的) ssh-copy-id root服务器i…

算法系列--动态规划--背包问题(2)--01背包拓展题目

💕"2024.3.28小米汽车发布"💕 作者:Lvzi 文章主要内容:算法系列–动态规划–背包问题(2)–01背包拓展题目 大家好,今天为大家带来的是算法系列--动态规划--背包问题(2)--01背包拓展题目 1.分割等和⼦集 链接: https:/…

史上最全-Java面试题(涵盖基础、高级、框架、微服务、中间件、大厂真题等28个大类超3000+面试题,全部附带详细答案)

3月4月又到了一年一度的跳槽黄金期,无论几年经验,也无论技术能力如何,跳槽前都离不开面试准备,其中刷面试题是重中之重。 刷面试题的时候一大痛点就是太分散了,需要自己根据知识点一项一项的去搜,容易遗漏知识点而且面试题质量无法保证,非常痛苦,基于此我花了两个月的…

微信小程序修改checkbox和radio的样式

我们在开发小程序的时候,有时候需要修改小程序中checkbox和radio的原生样式,如何修改呢?这里给大家提供了一份代码,大家可以试试。 首先是修改checkbox样式的代码: /* 重写 checkbox 样式 */ /* 未选中的 背景样式 *…

AMS概念以及面试相关整理

1、ActivityManagerService是什么?什么时候初始化的?有什么作用? ActivityManagerService(AMS)是什么? ActivityManagerService(简称AMS)是Android操作系统中的一个核心服务&#…

实现简易的 axios

1、实现逻辑 Promise XMLHttpRequest 封装 ① 返回一个 promise 实例 new XMLHttpRequest 并设置默认请求方式、请求根路径; 添加请求响应事件; 根据状态码,对应执行成功或者失败的调用函数,并把结果传进去; ② …

场内基金的折溢价

场内基金会出现折溢价&#xff0c;主要原因是场内基金有申购赎回&#xff0c;买入卖出这两套操作。 交易价格<基金净值&#xff0c;就是折价 交易价格>基金净值&#xff0c;就是溢价 如何判断场内基金的折溢价 ETF最好判断&#xff0c;有实时净值IOPV&#xff0c;交易价…

AOP切入点表达式基本格式

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 官方地址 https://docs.spring.io/spring-framework/reference/core/aop/ataspectj/pointcuts.html AOP切入点表达式基本格式如下&#xff1a; execution(modifiers-patte…

java针对:Sharing is only supported问题解决

#错误解决 当你运行出现报错&#xff1a;Java HotSpot™ 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended 问题翻译&#xff1a;Java HotSpot™ 64 位服务器 VM 警告&#xff1a;仅引导加载程序类…

OneDiff加速“图生生”,解锁电商AI图像处理新范式

2024年&#xff0c;电商领域正目睹生成式AI软件工具的飞速发展&#xff0c;AI Generated Content (AIGC) 技术在电商应用中的普及率正在显著提升&#xff0c;这类技术能够显著提高商业运营的效率&#xff0c;并促进业绩的稳步增长。 硅基流动研发的图片/视频生成推理引擎OneDif…

Linux:Jenkins:参数化版本回滚(6)

上几章我讲到了自动集成和部署 Linux&#xff1a;Jenkins全自动持续集成持续部署&#xff08;4&#xff09;-CSDN博客https://blog.csdn.net/w14768855/article/details/136977106 当我们觉得这个页面不行的时候&#xff0c;需要进行版本回滚&#xff0c;回滚方法我这里准备了…

电脑病毒详解(有bat版本 附代码)

众所周知&#xff0c;电脑病毒是所有用电脑的人最怕的东西。 它们是一种恶意软件&#xff0c;旨在破坏、感染或干扰计算机系统的正常运行。它们通过潜入计算机系统并在后台执行恶意代码来实现其目的。病毒可以通过互联网、可移动媒介&#xff08;如USB驱动器&#xff09;或下载…

Java基础知识总结(26)

MyBatis MyBatis框架解决的问题&#xff1a; 减轻使用JDBC的复杂性&#xff0c;不用编写重复的常见connection,Statement;不用编写关闭资源代码。直接使用java对象&#xff0c;表示结果数据。让开发者专注SQL的处理。其他分心的工作由MyBatis代劳。 三层架构 UI:&#xff0…

如何更好地收集软件需求并快速转换成软件功能

摘要 在软件开发过程中&#xff0c;需求收集与转换是确保项目成功的关键环节。本文详细探讨了如何更有效地收集软件需求&#xff0c;并迅速将这些需求转化为实际的软件功能&#xff0c;涉及的方法包括深入的用户研究、原型设计、敏捷开发方法以及持续的反馈循环。 关键词&…

【华为OD机试】机器人搬砖【C卷|100分】

题目描述 机器人搬砖,一共有N堆砖存放在N个不同的仓库中,第i堆砖中有bricks[i]块砖头, 要求在8小时内搬完。机器人每小时能搬砖的数量取决于有多少能量格, 机器人一个小时中只能在一个仓库中搬砖,机器人的能量格每小时补充一次且能量格只在这一个小时有效,为使得机器人损…

Hello算法2:复杂度分析

Hello算法2&#xff1a;复杂度分析 本文是基于k神的Hello 算法的读书笔记&#xff0c;请支持实体书。 https://www.hello-algo.com/chapter_paperbook/ 算法效率 算法效率评估 设计算法时&#xff0c;我们追求以下两个目标&#xff1a; 找出解法找出最优解 最优解通常包含…

Java 8中的Stream API及其用途详解

Java 8中的Stream API是Java函数式编程的一个核心组成部分&#xff0c;它允许你以声明性方式处理数据集合&#xff08;如列表、集合等&#xff09;。通过使用Stream API&#xff0c;你可以更方便地执行复杂的操作&#xff0c;如过滤、映射、排序和聚合&#xff0c;而无需编写大…

部署实施案例分析题

习题一 随着医院信息化程度的不断提高&#xff0c;各业务系统的全面上线&#xff0c;对IT基础架构的安全性、稳定性以及业务系统的连续性提出了较高的要求&#xff0c;运维工作也相同面临了前所未有的挑战。 为加强该医院的运维工作的规范化&#xff0c;并提高日常运维的工作…

实验7 内置对象response

编写代码&#xff0c;掌握request、response的用法。【参考课本4.6.2】 三、源代码以及执行结果截图&#xff1a; input.jsp <% page language"java" contentType"text/html; charsetutf-8" pageEncoding"utf-8"%> <!DOCTYPE html>…