【Redis】一文搞懂 Redis 中的缓存穿透、缓存击穿、缓存雪崩及其解决方案

news2024/11/24 8:37:05

一文搞懂 Redis 中的缓存穿透、缓存击穿、缓存雪崩及其解决方案

  • 1. 缓存穿透
    • 1.1 什么是缓存穿透
    • 1.2 缓存穿透的解决方案
      • 1.2.1 缓存空对象
      • 1.2.2 布隆过滤器
        • 布隆过滤器工作原理
        • Redis 使用布隆过滤器
  • 2. 缓存击穿
    • 1.1 什么是缓存击穿
    • 1.2 缓存击穿的解决方案
      • 1.2.1 设置热点数据永不过期
        • 物理不过期
        • 逻辑不过期
      • 1.2.2 分布式锁
  • 3. 缓存雪崩
    • 1.1 什么是缓存雪崩
    • 1.2 缓存雪崩的解决方案
      • 1.2.1 均匀过期
      • 1.2.2 加分布式锁
      • 1.2.3 缓存永不过期

在生产环境中使用 Redis 的时候,有时遇到缓存异常的场景:缓存穿透、缓存击穿、缓存雪崩等。学习这些缓存异常出现的原因及其解决办法,能够帮助我们提高系统的可靠性和可用性。

先来看一张图,大致了解一下 缓存穿透、缓存击穿、缓存雪崩 的描述和解决方案:

在这里插入图片描述

1. 缓存穿透

1.1 什么是缓存穿透

缓存穿透是指客户端查询一个缓存、数据库都不存在的数据,导致客户端每次请求数据都会透过缓存,直接查询数据库,返回 null 给客户端。

如果有恶意攻击者不断请求系统中不存在的数据,会导致短时间大量请求落在数据库上,造成数据库压力过大,甚至击垮数据库系统。

1.2 缓存穿透的解决方案

1.2.1 缓存空对象

如果缓存、数据库里都没数据 -> 缓存设置一个空缓存 -> key: {}

伪代码:

goods = redisUtil.get(goodsKey);
if (goods.equals("{}")) {
    return null;
}

if (goods == null) {
    goods = queryMySQL();
    if(goods = null){
        redisUtil.set(goodsKey, "{}");
        return null;
    }

    redisUtil.set(goodsKey, goods);
    return goods;
}

问题:可能会存在大量空缓存,占用缓存空间。

解决方案:设置缓存过期时间 -> 3min 过期,请求同一个商品设置 key 延期(在这段时间可能会存在缓存和持久层数据不一致的场景)。

1.2.2 布隆过滤器

Redis 布隆过滤器

布隆过滤器工作原理

布隆过滤器(Bloom Filter)是一个高空间利用率的概率性数据结构,由二进制向量(即位数组)和一系列随机映射函数(即哈希函数)两部分组成。

布隆过滤器使用exists()来判断某个元素是否存在于自身结构中。当布隆过滤器判定某个值存在时,其实这个值只是有可能存在(这个误判概率大约在 1% 左右);当它说某个值不存在时,那这个值肯定不存在

  1. 工作流程 - 添加元素

布隆过滤器主要由位数组和一系列 hash 函数构成,其中位数组的初始状态都为 0。

下面对布隆过滤器工作流程做简单描述,如下图所示:

在这里插入图片描述

当使用布隆过滤器添加 key 时,会使用不同的 hash 函数对 key 存储的元素值进行哈希计算,从而会得到多个哈希值。根据哈希值计算出一个整数索引值,将该索引值与位数组长度做取余运算,最终得到一个位数组位置,并将该位置的值变为 1。每个 hash 函数都会计算出一个不同的位置,然后把数组中与之对应的位置变为 1。通过上述过程就完成了元素添加(add)操作。

  1. 工作流程 - 判定元素是否存在

当我们需要判断一个元素是否存时,其流程如下:首先对给定元素再次执行哈希计算,得到与添加元素时相同的位数组位置,判断所得位置是否都为 1,如果其中有一个为 0,那么说明元素不存在,若都为 1,则说明元素有可能存在。

  1. 为什么是可能 “存在”

那些被置为 1 的位置也可能是由于其他元素的操作而改变的。比如,元素1 和 元素2,这两个元素同时将一个位置变为了 1(图1所示)。在这种情况下,我们就不能判定 “元素 1” 一定存在,这是布隆过滤器存在误判的根本原因。

Redis 使用布隆过滤器

  1. 将元素添加到布隆过滤器;

  2. 判断元素是否存在布隆过滤器;

  3. 不存在则返回 null,存在则查询缓存、数据库。

2. 缓存击穿

1.1 什么是缓存击穿

缓存击穿是指,当缓存中的某个热点数据(key)过期了,在该热点数据重新载入之前,有大量的请求穿过缓存,直接查询数据库。这种情况会导致数据库压力瞬间骤增,造成大量请求阻塞,甚至直接挂掉。

1.2 缓存击穿的解决方案

1.2.1 设置热点数据永不过期

永不过期实际包含两层意思:

物理不过期

针对热点 key 不设置过期时间

逻辑不过期

把过期时间存在 key 对应的 value 里,如果发现要过期了,通过一个后台的异步线程进行缓存的构建

从实战看这种方法对于性能非常友好,唯一不足的就是构建缓存时候,其余线程(非构建缓存的线程)可能访问的是老数据,对于不追求严格强一致性的系统是可以接受的。

1.2.2 分布式锁

锁的对象就是 key,这样,当大量查询同一个 key 的请求并发进来时,只能有一个请求获取到锁,然后获取到锁的线程查询数据库,然后将结果放入到缓存中,然后释放锁,此时,其他处于锁等待的请求即可继续执行,由于此时缓存中已经有了数据,所以直接从缓存中获取到数据返回,并不会查询数据库。

3. 缓存雪崩

1.1 什么是缓存雪崩

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

1.2 缓存雪崩的解决方案

针对缓存中有大量的 key 在同一时刻过期,出现缓存雪崩,有如下方案:

1.2.1 均匀过期

设置不同的过期时间,让缓存失效的时间点尽量均匀。通常可以为有效期增加随机值或者统一规划有效期

1.2.2 加分布式锁

跟缓存击穿解决思路一致,同一时间只让一个线程构建缓存,其他线程阻塞排队。

1.2.3 缓存永不过期

跟缓存击穿解决思路一致,缓存在物理上永远不过期,用一个异步的线程更新缓存。

对于 Redis 直接宕机出现缓存雪崩:

部署 Redis 时可以使用 Redis 的几种高可用方案部署:

  1. 主从(masterslave)架构
  2. 哨兵(sentinel)机制
  3. Redis集群(Redis Cluster)机构

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

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

相关文章

【无限思维画布】制作思维导图第三步,节点移动与编辑

正在为无限词典制作单词思维导图功能,实现无限单词导图,无限思维画布。目前制作到第三步,实现节点移动与编辑: 节点移动与编辑Details 第一步,搜索 github。 一个是比较完善的,基于普通dom,用…

Random(二)什么是伪共享?@sun.misc.Contended注解

目录1.背景简介2.伪共享问题3.问题解决4.JDK使用示例1.背景简介 我们知道,CPU 是不能直接访问内存的,数据都是从高速缓存中加载到寄存器的,高速缓存又有 L1,L2,L3 等层级。在这里,我们先简化这些复杂的层级…

对象创建的过程

对象创建的过程 在语言层面上,创建对象通常仅仅是一个new关键字而已(例外:复制、反序列化); 而在虚拟机中,对象的创建又是怎样一个过程呢?(文中讨论的对象限于普通Java对象&#xff…

Jetpack Compose 深入探索系列一:Composable 函数

Composable 函数的含义 如果我们只专注于简单的语法,任何标准的Kotlin函数都可以成为一个可组合函数,只需将其注解为Composable: 通过这样做,我们实际上是在告诉编译器,该函数打算将一些数据转换为一个Node节点,以便注…

Simulink建模:如何学习Simulink建模

本文介绍博主自己学习Simulink建模的方法。后续博客都会按照本文中的思路来记录博主学习的过程。 文章目录1 Simulink建模的分类1.1 连续模型建模1.2 物理模型建模1.3 控制算法建模2 控制算法建模的基本知识2.1 控制算法与电控软件架构2.2 控制算法与周期调度2.3 控制算法与其他…

分布式-分布式缓存笔记

分布式系统缓存 缓存分类 前端缓存 前端缓存包括页面和浏览器缓存,如果是 App,那么在 App 端也会有缓存。当你打开商品详情页,除了首次打开以外,后面重复刷新时,页面上加载的信息来自多种缓存。 页面缓存属于客户端…

61 - 进程互斥锁的详细设计

---- 整理自狄泰软件唐佐林老师课程 文章目录1. 问题1.1 生活中的示例1.1.1 吃饭问题1.1.2 十字路口1.1.3 洗手间1.1.4 生产消费者问题1.2 结论2. 接下来的问题2.1 临界资源(Critical Resource)2.2 临界区(Critical Section)2.3 任…

【C3】cpu_wtd_sysfs

文章目录2.cpu_wtd_sysfs:switchboard.c (fpga下i2c访问Switch CPLD1,Switch CPLD2 :CPLD, FPGA , QSFP)scriptbmc_wtd:syscpld.c中wd_en和wd_kick节点对应寄存器,crontab,FUNCNAMEA…

Spring事务的隔离级别

事务的特性: 隔离性:多个事务在并发执行的时候,多个事务执行的一个行为模式,当一个事务执行的时候,另一个事务执行的一个行为模式是什么? 1)A,原子性,一个事务中的所有操作,要么全部执行成功&am…

I2C误码了怎么处理

我相信不少人有遇到I2C设备识别不到,或者概率性误码。 我相信大部分工程师的做法如下: 1.调整上拉电阻的大小,然后重新老化测试; 2.降低I2C速率,然后老化测试; 3.软件加入一定判断条件,将能…

Ncvicat 打开sql文件方法

Nacicat打开sql文件时,有比较多的文章介绍可以直接打开,方法介绍的比较多,但是我遇到了一个坑,就是如何配置环境都无法打开。 本机环境: windows10 mysql 5.7.40 Navicat12.1 一、遇到问题情况 1.1、通过navicat…

Kubernetes向集群外部暴露服务的方式你知道吗?

Kubernetes向进群外暴露服务的方式有三种:Ingress、LoadBlancer类型的Service、NodePort类型的Service。IngressIngress相当于service的service,可以将外部请求通过按照不同规则转发到对应的service。实际上,ingress相当于一个7层的负载均衡器…

面了一个月,终于让我总结出了这份最详细的接口测试面试题

目录 1、你们公司是如何做接口测试的? 2、什么时候开展接⼝测试? 3、接⼝测试和UI测试的工作是否重复? 4、接口测试框架怎么搭建? 5、接⼝之间有依赖时怎么处理? 6、如何判断接⼝测试的结果(成功或失败&a…

【C进阶】指针的高级话题

文章目录:star:1. 字符指针:star:2. 指针数组2.1 指针数组的定义2.2 指针数组的使用:star:3. 数组指针3.1 数组的地址3.2 数组指针的使用:star:4. 数组参数和指针参数:star:5. 函数指针5.1 函数名和函数的地址5.2 练习:star:6. 函数指针数组6.1 转移表:star:7. 指向函数指针数组…

昌德科技冲刺上市:计划募资约12亿元,蒋卫和为实控人

近日,深圳市昌德新材科技股份有限公司(下称“昌德科技”)递交招股书,准备在真真证券交易所主板上市。本次冲刺上市,昌德科技计划募资11.69亿元,中信建投证券为其保荐机构。 据招股书介绍,昌德科…

西电编译原理期末核心考点汇总(期末真题+相关知识点)

文章目录前言一、正规式1.1 相关知识点1.1.1 正规式定义1.1.2 辅助定义1.2 历年真题二、二义文法2.1 相关知识点2.1.1 二义性概念2.2 历年考题三、全部短语、直接短语和句柄3.1 相关知识点3.1.1 短语,直接短语和句柄定义3.1.2 短语,直接短语和句柄例题3.…

【企业管理】研发部视角提出对外支撑业务自助门户构思和实现

导读:公司是由不同部门组成,各个部门之间必然有协同才能使得公司各项职能正常运行。可以说公司的竞争力越强往往会得出公司内部之间工作协同就越高效,可以看出公司各部门之间协同对公司营运是十分重要的。高效协同前提必然是实现便利的信息共…

数据库设计表与表之间的关系详细介绍

文章目录数据库设计数据库设计简介表关系之一对多表关系之多对多表关系之一对一数据库设计 数据库设计简介 软件研发的步骤如下: 设计数据库还是很重要的 数据库设计概念: 数据库设计就是根据业务系统的具体需求,结合我们所选用的DBMS,为这个业务系统构…

Synology搭建Gitea(Docker)

Synology搭建Gitea(Docker) 文章目录Synology搭建Gitea(Docker)参考增加用户与用户组增加映像安装配置反向代理路由器端口转发参考 Nas轻量git方案:Docker安装Gitea;群晖(Synology) NAS 如何安装 gitea 增加用户与用户组 为所有Docer创建一个组docker; 权…

行测-判断推理-图形推理-样式规律-黑白运算

黑白元素个数不同,优先考虑黑白运算白白白黑黑白黑白黑选A考试时,这种题不要先把规律全部推出来,再去做题,太慢了直接看要推的图,通过排除法选答案黑白元素个数不同,优先考虑黑白运算白白白黑黑白黑白黑选B…