当前位置: 首页 > news >正文

【白话Redis】缓存雪崩、穿透、击穿、失效和热点缓存重建

快速导航

  • Redis不可不知的故障现象
    • 一、缓存雪崩
      • 定义:
      • 解决方案:
    • 二、缓存穿透
      • 定义:
      • 解决方案一:
      • 解决方案二(更普遍的做法):
    • 三、缓存击穿
      • 定义:
      • 解决方案:
    • 四、缓存失效
      • Redis缓存失效的情况:
    • 五、热点缓存重建
      • 1. 预热机制
      • 2. 异步重建
      • 3. 分布式锁
      • 4. 缓存预热与更新策略
      • 5. 缓存降级与容错
      • 6. 其他考虑因素

Redis不可不知的故障现象

一、缓存雪崩

定义:

由缓存机器故障宕机,导致大量请求全部落到数据库,超出了数据库的处理能力极限,进而导致数据库压力增大、宕机的情况。

解决方案:

  • 事前:Redis集群部署,主从+哨兵,避免全盘奔溃
  • 事中:本地缓存 + 限流&降级,避免数据库压力过大宕机
  • 事后:Redis持久化,机器重启后可以自动从磁盘加载数据,恢复缓存数据

二、缓存穿透

定义:

大批量请求缓存和数据库中都不存在的数据,导致数据库压力变大,甚至宕机。

解决方案一:

查询的key比较集中的时候,可以在查询数据库结束后给缓存中写一个空值或者默认值进去。设置一个过期时间,避免后续的大量请求落到数据库。

解决方案二(更普遍的做法):

在系统和缓存之间使用布隆过滤器,将数据库中所有可能的数据哈希映射到布隆过滤器中。
在请求到布隆过滤器时判断:

  • 若请求数据的key不存在布隆过滤器中,直接返回不存在(可以确定该数据也一定不存在于数据库)
  • 若请求数据的key在布隆过滤器中存在,则继续查询缓存

三、缓存击穿

定义:

某个热点key访问非常频繁,且请求时间比较集中,是高并发场景。当这个key失效的瞬间,大量的请求直接落到数据库,导致数据库压力骤增,甚至宕机。

解决方案:

  • 基本不更新的热点数据,设置为永不过期
  • 更新不频繁且缓存刷新流程耗时较少的情况下,可以基于互斥锁保证较少量的请求落到数据库,并重新构建缓存,而其他线程在锁释放后可访问新缓存。
  • 缓存数据更新频繁或者缓存刷新耗时较长的情况下,可以利用设置定时任务在任务过期前主动重新构建缓存或延后过期时间,以保证请求能一直访问到缓存

四、缓存失效

Redis缓存失效的情况:

1. 过期时间到期:

  • Redis缓存可以设置过期时间,当缓存的过期时间到达后,缓存数据会自动失效。

  • 解决方案: 合理设置缓存的过期时间,避免缓存数据过早或过晚失效。同时,可以考虑使用动态过期时间策略,根据数据的实际使用情况调整过期时间。

2. 内存不足:

  • 当Redis的内存使用达到上限时,Redis会根据配置的淘汰策略(如LRU算法)自动删除部分缓存数据,以释放内存空间。
  • 解决方案: 监控Redis的内存使用情况,及时升级Redis的内存配置或优化缓存策略,如减少不必要的缓存数据、增加缓存的复用率等。

3. 手动删除:

  • 管理员或开发者可能会通过Redis客户端命令手动删除缓存数据。
  • 解决方案: 建立规范的缓存操作流程,确保只有授权人员才能对缓存进行删除操作。同时,可以通过日志记录缓存的删除操作,以便追溯和审计。

4. 服务器重启:

  • Redis服务器重启时,所有缓存数据会丢失(除非使用了持久化功能)。
  • 解决方案: 配置Redis的持久化功能(如RDB或AOF),确保在服务器重启后能够恢复缓存数据。

5. 数据更新:

  • 当缓存数据对应的数据库数据发生更新时,如果缓存没有及时更新,就会导致缓存失效。
  • 解决方案: 实现缓存与数据库数据的一致性同步机制,如使用消息队列或订阅数据库变更日志来实时更新缓存数据。

6. 分布式环境下的缓存失效:

  • 在分布式系统中,多个应用节点可能同时使用同一个Redis缓存。如果某个节点修改了缓存数据,其他节点的缓存可能会失效。
  • 解决方案: 使用分布式锁或其他同步机制来确保在分布式环境下缓存数据的一致性。

7. 缓存雪崩:

  • 当大量缓存数据同时失效时,大量请求会涌入数据库,可能导致系统崩溃。
  • 解决方案: 设置随机过期时间以避免缓存同时失效;使用多级缓存策略;实施缓存标记策略;通过主从复制和哨兵机制提高Redis的高可用性;使用第三方插件如RocketMQ自动更新缓存等。

解决方案总结

  • 合理设置缓存过期时间:根据数据的实际使用情况设置合理的过期时间。
  • 监控和优化内存使用:定期监控Redis的内存使用情况,并优化缓存策略以减少内存消耗。
  • 规范缓存操作:建立规范的缓存操作流程,确保只有授权人员才能对缓存进行删除等操作。
  • 配置持久化功能:启用Redis的持久化功能,确保在服务器重启后能够恢复缓存数据。
  • 实现缓存与数据库的一致性同步:通过消息队列或订阅数据库变更日志等方式实现缓存与数据库数据的一致性同步。
  • 应对分布式环境下的缓存失效:使用分布式锁或其他同步机制来确保缓存数据的一致性。
  • 防范缓存雪崩:采取多种策略来避免缓存雪崩的发生,如设置随机过期时间、使用多级缓存、实施缓存标记策略等。

五、热点缓存重建

1. 预热机制

  • 定义:在系统启动或重启时,提前将预测会频繁访问的热点数据加载到缓存中。
  • 实现方式:
    • 通过定时任务在系统启动时执行数据加载。
    • 利用系统启动时的初始化代码加载数据。
    • 通过模拟请求或默认请求来预热缓存。
  • 优势:避免了系统启动初期的缓存穿透问题,提高了系统的启动速度和稳定性。

2. 异步重建

  • 定义:当热点缓存失效时,不立即阻塞请求线程去重建缓存,而是通过异步任务或消息队列等方式来重建缓存。
  • 实现方式:
    • 在缓存失效时,发布一个缓存失效事件到消息队列。
    • 系统中设置一个监听器来监听这些事件,一旦监听到失效事件,就启动一个异步线程去重建缓存。
    • 异步线程可以从数据库中获取数据,并将数据写回缓存。
  • 优势:降低了对系统实时性能的影响,使系统能够平滑处理高并发请求。

3. 分布式锁

  • 定义:在缓存重建过程中,使用分布式锁来确保同一时间只有一个线程或进程在重建缓存。
  • 实现方式:
    • 当缓存失效时,尝试获取分布式锁。
    • 如果获取锁成功,则进行缓存重建操作;如果获取锁失败,则等待或重试。
    • 缓存重建完成后,释放分布式锁。
  • 优势:避免了多个线程或进程同时重建缓存导致的资源浪费和竞态条件。

4. 缓存预热与更新策略

  • 策略一:在系统启动或业务低峰期,通过预热机制加载热点数据。
  • 策略二:定期更新缓存中的热点数据,确保数据的新鲜度。可以使用定时任务或监控机制来触发更新操作。
  • 策略三:根据缓存的访问频率和数据的变化情况,动态调整缓存的过期时间和重建策略。

5. 缓存降级与容错

  • 缓存降级:在缓存重建过程中,如果发生错误或异常,可以实施缓存降级策略,如返回默认值、空值或缓存中的旧数据,以避免系统崩溃。
  • 容错机制:确保缓存系统具有容错能力,能够在遇到硬件故障、网络问题等异常情况时,仍能提供一定程度的服务。

6. 其他考虑因素

  • 数据一致性:在缓存重建过程中,需要确保缓存数据与数据库数据的一致性。可以采用双写、延时双删或订阅数据库变更日志等方式来实现。
  • 性能监控:对缓存的访问情况、命中率、重建时间等进行实时监控,以便及时发现并解决潜在的性能问题。

相关文章:

【白话Redis】缓存雪崩、穿透、击穿、失效和热点缓存重建

快速导航 Redis不可不知的故障现象一、缓存雪崩定义:解决方案: 二、缓存穿透定义:解决方案一:解决方案二(更普遍的做法): 三、缓存击穿定义:解决方案: 四、缓存失效Redis…...

flink增量检查点降低状态依赖实现的详细步骤

增量检查点启动恢复的时间是很久的,业务上不能接受,所以可以通过降低状态依赖来减少恢复的时间。 降低状态依赖 尽可能减少状态的复杂性和依赖关系,通过拆分状态或将状态外部化到其他服务中,从而降低恢复的开销。 实施措施&…...

Redis总结,是什么,干什么,怎么利用?

Redis(Remote Dictionary Server)是一个开源的内存数据库,遵守 BSD 协议,它提供了一个高性能的键值(key-value)存储系统,常用于缓存、消息队列、会话存储等应用场景 Redis主要特性 &#xff08…...

Vue3状态管理Pinia

Vue3 的 Pinia 使用指南 Pinia 是 Vue3 中官方推荐的状态管理库,作为 Vuex 的替代品,它更简洁易用,并且支持模块化、类型推断和 DevTools 集成。Pinia 非常适合在 Vue3 项目中管理全局状态。 1. 安装 Pinia 首先,我们需要在 Vu…...

box64 安装

ARM运行x86程序 docker安装 box64 安装方法 docker run --name a001 -itd --networkhost -v /www/wwwroot/docker/Box64/f:/f ubuntu:22.04 /bin/bash docker exec -it a001 bash cd /home //创建目录qq547176052 mkdir -p qq547176052 cd /home/qq547176052 apt update apt …...

OpenCV通过鼠标提前ROI(C++实现)

文章目录 鼠标绘制矩形提取ROI任意形状绘制提前ROI 废话不多说&#xff0c;直接上代码 鼠标绘制矩形提取ROI #include <iostream> #include <opencv2\opencv.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/core/core.hpp>us…...

6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)

目录 一.堆(Heap)的基本介绍 二.堆的常用操作&#xff08;以小根堆为例&#xff09; 三.实现代码 3.1 堆结构定义 3.2 向下调整算法* 3.3 初始化堆* 3.4 销毁堆 3.4 向上调整算法* 3.5 插入数据 3.6 删除数据 3.7 返回堆顶数据 四.下篇内容 1.堆排序 2.TopK问题 一…...

【智能终端】HBuilder X 与微信开发者工具集成与调试实战

目录 1. 需求和理解库、框架、平台 1.1 需求 1.2 理解 2.3 库、框架、平台 2.3.1 库&#xff08;Library&#xff09; 2.3.2 框架&#xff08;Framework&#xff09; 2.3.3 平台&#xff08;Platform&#xff09; 2.3.4 总结 2. 使用 HBuilder X 创建第一个 uni-app 应…...

结构体的字节对齐方式(__attribute_pack(packed))#pragma pack())

结构体的字节对齐方式&#xff08;__attribute_pack(packed))&#pragma pack()) 1、编译器的字节对齐方式 当前编译器都有默认的字节对齐方式&#xff0c; struct PackedStruct {char a;int b;short c; };如上代码段中的结构体&#xff0c;在编译运行后发现他的大小并不…...

若依Ruoyi之智能售货机运营管理系统(新增运营运维工单管理)

idea抽取独立方法快捷键&#xff1a;ctrlaltm TaskDto.java package com.dkd.manage.service.impl;import java.time.Duration; import java.util.List; import java.util.stream.Collectors;import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUti…...

ModuleNotFoundError: No module named ‘keras.layers.core‘怎么解决

问题 ModuleNotFoundError: No module named keras.layers.core&#xff0c;如图所示&#xff1a; 如何解决 将from keras.layers.core import Dense,Activation改为from tensorflow.keras.layers import Dense,Activation&#xff0c;如图所示&#xff1a; 顺利运行&#xf…...

C++(三)----内存管理

1.C/C内存分布 看下面这个问题&#xff08;考考你们之前学的咋样&#xff09;&#xff1a; int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] {1, 2, 3, 4};char char2[] "abcd";char* pCh…...

使用 ShuffleNet 模型在 CIFAR-100 数据集上的图像分类

简介 在深度学习领域&#xff0c;图像分类任务是衡量算法性能的重要基准。本文将介绍我们如何使用一种高效的卷积神经网络架构——ShuffleNet&#xff0c;来处理 CIFAR-100 数据集上的图像分类问题。 CIFAR-100 数据集简介 CIFAR-100 数据集是一个广泛使用的图像分类数据集&…...

怎么利用短信接口发送文字短信

在当今这个快节奏的数字时代&#xff0c;即时通讯已成为人们日常生活和工作中不可或缺的一部分。而短信接口&#xff08;SMS Interface&#xff09;&#xff0c;作为传统与现代通讯技术结合的典范&#xff0c;凭借其高效、稳定、广泛覆盖的特性&#xff0c;在众多领域发挥着不可…...

【C#生态园】提升C#开发效率:掌握这六款单元测试利器

从xUnit到SpecFlow&#xff1a;C#测试驱动开发全指南 前言 在C#开发中&#xff0c;单元测试和模拟框架是至关重要的工具&#xff0c;它们可以帮助开发人员确保代码的质量和可靠性。本文将介绍一些常用的C#单元测试框架和相关库&#xff0c;包括xUnit、NUnit、Moq、FluentAsse…...

【QT】自制一个简单的小闹钟,能够实现语音播报功能

做了一个自制的小闹钟&#xff0c;能够自己输入时间&#xff0c;以及对应的闹铃&#xff0c;时间到了自动播放设定的闹铃&#xff0c;可以随时取消重新设定&#xff0c;采用分文件编译 注意&#xff1a;需要在.pro文件中加入&#xff1a;QT core gui texttospeech 代码…...

基于深度学习的图像描述生成

基于深度学习的图像描述生成&#xff08;Image Captioning&#xff09;是一种将计算机视觉与自然语言处理结合的任务&#xff0c;其目标是通过自动生成自然语言来描述输入的图像。该技术能够理解图像中的视觉内容&#xff0c;并生成相应的文本描述&#xff0c;广泛应用于视觉问…...

Linux和C语言(Day11)

一、学习内容 讲解有参函数 形参 和 实参 形参——定义时的参数&#xff0c;形式上的参数&#xff0c;没有实际意义&#xff0c;语法上必须带有数据类型 void fun(int a,int b); void fun(int a[],int n); void fun(char *s); 可以是&#xff1a;变量、数组、指针 实参——调用…...

使用Zlib库进行多文件或者多文件夹的压缩解压缩

zlib库可在git上自己clone下来然后使用cmake工具生成解决方案&#xff0c;编译、生成zlib二进制文件。然后将zlib库引入项目&#xff1a; //zlib库支持 #include "../zlib/include/zlib.h" #ifdef _DEBUG #pragma comment(lib, "../zlib/lib/zlibd.lib") …...

CSGHub携手Nvidia NIM、阿里计算巢打造企业级私有化部署解决方案

强强联合 人工智能与大数据的迅速发展&#xff0c;大模型的推理应用和资产管理已成为企业数字化转型的重要组成部分&#xff0c;企业正寻求高效、安全的AI模型部署解决方案。为应对日益增长的计算需求和复杂的数据管理挑战&#xff0c;CSGHub、Nvidia和阿里云计算巢强强联手&a…...

opencv的球面投影

cv::detail::SphericalProjector 在全景图像拼接任务中&#xff0c;可能需要对多个图像进行球面投影以实现无缝拼接。每个cv::detail::SphericalProjector可以负责一个图像的球面投影操作。通过将多个这样的投影器存储在std::vector中&#xff0c;可以对一组图像依次进行投影处…...

5. 去中心化应用(dApp)

去中心化应用&#xff08;dApp&#xff09; 去中心化应用&#xff08;dApp&#xff09;是基于区块链技术构建的应用程序&#xff0c;其核心特性是去中心化、透明和开放。dApp与传统应用有许多显著的区别&#xff0c;它们在实现和功能上都带来了新的变革。以下是对dApp的详细介…...

k8s服务发布Ingress

Kubernetes暴露服务的方式目前只有三种&#xff1a;LoadBlancer Service、NodePort Service、Ingress&#xff0c;通俗来讲&#xff0c;ingress和之前提到的Service、Deployment&#xff0c;也是一个k8s的资源类型&#xff0c;ingress用于实现用域名的方式访问k8s内部应用。 In…...

区块链学习笔记1--比特币

区块链是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。 从狭义上来说&#xff1a;区块链是一种按照时间顺序将数据区块以顺序相连的方式组合成的一种链式数据结构&#xff0c;并以密码学的方式保证的不可篡改和不可伪造的分布式账本。 意思就是…...

在 Vite 项目中自动为每个 Vue 文件导入 base.less

在 Vue.js 项目中&#xff0c;使用 Less 作为 CSS 预处理器时&#xff0c;我们通常会创建一个全局的样式文件&#xff08;如 base.less&#xff09;&#xff0c;用于存放一些全局变量、混合、通用样式等。为了避免在每个 Vue 组件中手动导入这个文件&#xff0c;我们可以通过配…...

RUST 学习之全局变量

RUST 全局变量 rust 全局变量编译期初始化的全局变量静态常量静态变量原子类型的静态变量 运行期初始化的全局变量lazy_staticBox::leakOnceCell & OnceLock 参考文档 rust 全局变量 编译期初始化的全局变量 静态常量 在编译期初始化&#xff0c;所以其赋值只能是表达式…...

代码随想录八股训练营第三十九天| C++

前言 一、说一下 lambda函数&#xff1f; 1.1.Lambda 函数的一般语法如下: 1.2.捕获子句&#xff1a; 二、C 怎么实现一个单例模式&#xff1f; 2.1.懒汉式&#xff08;线程不安全&#xff09;: 2.2.饿汉式&#xff08;线程安全&#xff09;: 2.3.双重检查锁定&#xff…...

服务网关工作原理,如何获取用户真实IP?

文章目录 一、什么是网关二、网关工作原理 (★)三、SpringCloud Gateway3.1 Gateway 简介3.2 Gateway 环境搭建3.3 自定义路由规则 (★)3.4 局部过滤器3.5 全局过滤器&#xff08;案例&#xff1a;获取用户真实IP地址&#xff09; (★) 补充1&#xff1a;不同类型的客户端如何设…...

单链表的实现(C语言)

目录 1.单链表 1.1 实现单链表 1.1.1 文件创建 1.1.2 链表功能了解 1.1.3 链表的结点 1.1.4 链表的函数声明 1.1.5 链表功能的实现 链表是一种链式结构&#xff0c;物理结构不连续&#xff0c;逻辑结构是连续的&#xff0c;在计算机中链表的实际存储是按照一个结点内存放…...

sql语句的训练2024/9/9

1题 需要看清思路&#xff1a;不是将数据库中的device_id的名字改为user_infors_example&#xff0c;而是在查找的时候&#xff0c;需要将device_id看成user_infors_example来进行查找。 答案 select device_id AS user_infos_example FROM user_profile limit 2 2 当固定查找…...