Redis——缓存雪崩、击穿、穿透

缓存雪崩

大量缓存数据在同一时间过期或者Redis故障宕机时,若此时有大量请求,都会直接访问到数据库,导致数据库压力倍增甚至宕机。

大量数据同时过期解决方案:

1、均匀设置过期时间:

设置过期时间的时候可以追加一个随机数避免数据同一时间过期

2、互斥锁:

业务线程处理用户请求时,如果发现访问的数据不在Redis里,则加入互斥锁,保证同一时间只有一个业务线程访问数据库并构建缓存未获取到互斥锁的请求要么等待锁释放后获取缓存,要么返回指定值。注意:互斥锁应该设置过期时间避免获取锁的线程意外阻塞导致锁无法释放,造成无响应的情况。

3、后台更新缓存:

将更新缓存的工作交给后台线程进行更新

  • 第一种方式:后台频繁检测缓存是否有效,检测到缓存失效后(可能是内存资源不足被淘汰的)就马上访问数据库并更新到缓存。
  • 缺点:
    • 检测时间间隔不能太长,一般是毫秒级,有延迟问题
    • 频繁检测存在性能开销
  • 第二种方式:业务线程发现缓存失效后,通过消息队列发送一条信息通知后台线程更新缓存。后台线程收到消息后进行判断数据是否已被缓存,没有则访问数据库构建缓存
  • 优点:
    • 消息队列中可根据相同请求幂等性实现互斥锁的效果,无需加锁,所有请求都等待缓存构建或返回指定值即可。
    • 消息队列具有削峰作用,高并发时也能保证数据库正常运行

业务刚上线时我们就可以提前把数据缓存起来,而不是等待用户来触发缓存构建,这就是所谓的缓存预热

Redis宕机解决方案:

1、服务熔断或请求限流机制
  • 服务熔断机制暂停业务对缓存服务的访问,直接返回错误,而不是继续访问数据库,直到Redis恢复正常。
  • 请求限流机制只接收少部分请求发送到数据库进行处理,再多的请求就在入口直接拒绝服务,直到待Redis恢复正常
2、构建Redis高可靠集群

当前Redis宕机后依然可通过其他从节点获取缓存。

缓存击穿

缓存中的某个热点数据过期,此时大量请求直接访问到数据库。(缓存雪崩是多种多个数据请求缓存击穿是访问热点数据的大量请求

解决方案:

  • 互斥锁:保证同一时间只有应该业务线程共享缓存。
  • 后台异步更新缓存:不再给热点请求设置过期时间,或热点数据快过期时通知后台线程更新缓存并重新设置缓存时间。

缓存穿透

发生缓冲雪崩或击穿时,数据库中是有对应数据的,而缓冲穿透则是数据库中也无法获取到对应数据的情况。如果数据库无法获取数据就无法构建缓存,造成缓存失效。通常发生于业务误操作删除了数据恶意访问不存在的数据

解决方案:

1、限制非法请求:

在访问缓存或数据库前判断请求的参数是否合理,过滤不合理请求

2、缓存空值或默认值

若业务发现有缓存穿透的现象,可以针对查询数据在缓存中设置空值或者默认值

3、布隆过滤器

使用布隆过滤器快速判断数据是否存在,避免通过查询数据库来判断

布隆过滤器的实现:

初始值都为0的位图数组(Bitmap,连续二进制位序列)和N个哈希函数两部分组成。我们在写入数据库数据的同时对布隆过滤器做标记,这样后续的查询就可根据布隆过滤器快速判断数据是否存在。

过滤操作:
  • 第一步,使用N个哈希函数分别对数据进行哈希计算得到N个哈希值
  • 第二步,将第一步得到的N个哈希值对位图数组的长度进行取模得到每个哈希值的对应位置
  • 第三步,将每个哈希值在位图数组中的对应位置设为1

假设有一个长度为8的位图数组,3个哈希函数的布隆过滤器:

查询时,分别计算出数据N个哈希值对应的位置并判断是否全为1。只要有一个为0就说明数据不存在。

布隆过滤器也是存在哈希冲突的,哈希冲突时可能将不存在的查询数据误判为已存在(与数据库中存在的数据发生了哈希冲突)。但数据库中不存在的数据在布隆过滤器中就一定不存在

通过增加哈希函数的数量,可尽量减少因为哈希冲突发生误判的情况

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

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

相关文章

开源GPU架构RISC-V VCIX的深度学习潜力测试:从RTL仿真到MNIST实战

点击 “AladdinEdu,同学们用得起的【H卡】算力平台”,H卡级别算力,按量计费,灵活弹性,顶级配置,学生专属优惠。 一、开篇:AI芯片架构演变的三重挑战 (引述TPUv4采用RISC-V的行业案…

字符串相乘(43)

43. 字符串相乘 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; class Solution { public:string multiply(string num1, string num2) {string res "0";for (int i 0; i < num2.size(); i) {string str multiplyOneNum(num1, num2[num2.size() -…

mathematics-2024《Graph Convolutional Network for Image Restoration: A Survey》

推荐深蓝学院的《深度神经网络加速&#xff1a;cuDNN 与 TensorRT》&#xff0c;课程面向就业&#xff0c;细致讲解CUDA运算的理论支撑与实践&#xff0c;学完可以系统化掌握CUDA基础编程知识以及TensorRT实战&#xff0c;并且能够利用GPU开发高性能、高并发的软件系统&#xf…

[LevelDB]LevelDB版本管理的黑魔法-为什么能在不锁表的情况下管理数据?

文章摘要 LevelDB的日志管理系统是怎么通过双链表来进行数据管理为什么LevelDB能够在不锁表的情况下进行日志新增 适用人群: 对版本管理机制有开发诉求&#xff0c;并且希望参考LevelDB的版本开发机制。数据库相关从业者的专业人士。计算机狂热爱好者&#xff0c;对计算机的…

【C++进阶篇】C++容器完全指南:掌握set和map的使用,提升编码效率

C容器的实践与应用&#xff1a;轻松掌握set、map与multimap的区别与用法 一. 序列式容器与关联式容器1.1 序列式容器 (Sequential Containers)1.2 关联式容器 (Associative Containers) 二. set系列使用2.1 set的构造和迭代器2.2 set的增删查2.2.1 插入2.2.2 查找2.2.3 删除 2.…

2_Spring【IOC容器中获取组件Bean】

Spring中IOC容器中获取组件Bean 实体类 //接口 public interface TestDemo {public void doSomething(); } // 实现类 public class HappyComponent implements TestDemo {public void doSomething() {System.out.println("HappyComponent is doing something...")…

安卓开饭-ScrollView内嵌套了多个RecyclerView,只想与其中一个RecyclerView有联动

在 Android 开发中&#xff0c;将 RecyclerView 嵌套在 ScrollView 内通常会导致性能问题和滚动冲突&#xff0c;应尽量避免这种设计。以下是原因和替代方案&#xff1a; 为什么不推荐 RecyclerView ScrollView&#xff1f;​​ 性能损耗​ RecyclerView 本身已自带高效回收复…

HTTP 请求中 Content-Type 头部

HTTP 请求中 Content-Type 头部可以设置的各种不同的传输格式。multipart/form-data 只是其中一种,主要用于传输包含文件的数据。 以下是一些常见的 HTTP 请求体的 Content-Type 及其用途: 常见的数据传输格式 (Content-Type) 列表: application/json: 描述: 用于传输 JSO…

【U-boot 命令使用】

文章目录 1 查询有哪些命令2 信息查询命令dbinfo - 查看板子信息printenv- 输出环境变量信息version - 输出uboot版本信息 3 环境变量操作命令修改环境变量新建环境变量删除环境变量 4 内存操作命令md命令nm命令mm命令mv命令cp命令cmp命令 5 网络操作命令与网络有关的环境变量p…

初学者如何用 Python 写第一个爬虫?

初学者如何用 Python 写第一个爬虫&#xff1f; 一、爬虫的基本概念 &#xff08;一&#xff09;爬虫的定义 爬虫&#xff0c;英文名为 Web Crawler&#xff0c;也被叫做网络蜘蛛、网络机器人。想象一下&#xff0c;有一个勤劳的小蜘蛛&#xff0c;在互联网这个巨大的蜘蛛网中…

IDE/IoT/搭建物联网(LiteOS)集成开发环境,基于 VSCode + IoT Link 插件

文章目录 概述IDE安装安装旧版本VSCode安装插件安装问题和解决手动安装SDK包手动下载依赖工具 IoTLink配置IoTLink Home用户设置-工具链-编译器用户设置-工具链-构建器用户设置-工具链-烧录器用户设置-SDK管理工程设置-SDK配置工程设置-编译器工程设置-调试器 创建工程Demo 源码…

深度剖析:Dify+Sanic+Vue+ECharts 搭建 Text2SQL 项目 sanic-web 的 Debug 实战

目录 项目背景介绍sanic-web Dify\_service handle\_think\_tag报错NoneType问题描述debug Dify调用不成功&#xff0c;一直转圈圈问题描述debug 前端markdown格式只显示前5页问题描述debug1. 修改代码2.重新构建1.1.3镜像3.更新sanic-web/docker/docker-compose.yaml4. 重新部…

理想AI Talk第二季-重点信息总结

一、TL&#xff1b;DR 理想为什么要做自己的基模&#xff1a;座舱家庭等特殊VLM场景&#xff0c;deepseek/openai没有解决理想的基模参数量&#xff1a;服务端-300B&#xff0c;VLencoder-32B/3.6B&#xff0c;日常工作使用-300B&#xff0c;VLA-4B为什么自动驾驶可以达成&…

TensorRT

TensorRT 下载 TensorRT 7.1.3.4 TAR压缩包&#xff0c;解压到安装目录&#xff1a; tar xzvf TensorRT-7.1.3.4.Ubuntu-16.04.x86_64-gnu.cuda-11.0.cudnn8.0.tar.gz 添加 TensorRT lib 到环境变量&#xff1a; gedit ~/.bashrc # 添加 export LD_LIBRARY_PATH$LD_LIBRARY_PAT…

【NGINX】 -9 nginx + tomcat实现的多级反向代理

文章目录 1、tomcat的安装 (centos版本)1.1 安装Java依赖环境1.2 安装tomcat 2、tomcat的虚拟主机的配置2.1 配置多级目录 3、利用nginx的反向代理实现将转发指向一个虚拟机3.1 nginx服务器的配置3.2 客户端配置 4、 反向多级代理代理服务器操作nginx 1 服务器nginx 2 服务器to…

基于requests_html的python爬虫

前言&#xff1a;今天介绍一个相对性能更高的爬虫库requests_html&#xff0c;会不会感觉和requests有点联系&#xff1f;是的。为什么开始不直接介绍呢&#xff1f;因为我觉得requests是最基本入门的东西&#xff0c;并且在学习过程中也能学到很多东西。我的python老师在介绍这…

【架构篇】架构类型解释

架构设计的本质&#xff1a;从模糊概念到系统化思维 摘要 “架构”是系统设计的灵魂&#xff0c;但许多人对它的理解仍停留在抽象层面。本文系统解析架构的8大核心维度&#xff0c;结合设计原则、案例与误区分析&#xff0c;帮助开发者建立从战略到落地的完整认知框架。 一、架…

用Python绘制梦幻星空

用Python绘制梦幻星空 在这篇教程中&#xff0c;我们将学习如何使用Python创建一个美丽的星空场景。我们将使用Python的图形库Pygame和随机库来创建闪烁的星星、流星和月亮&#xff0c;打造一个动态的夜空效果。 项目概述 我们将实现以下功能&#xff1a; 创建深蓝色的夜…

PyTorch循环神经网络(Pytotch)

文章目录 循环神经网络&#xff08;RNN&#xff09;简单的循环神经网络长短期记忆网络&#xff08;LSTM&#xff09;门控循环单元&#xff08;GRU&#xff09; 循环神经网络&#xff08;RNN&#xff09; 循环神经网络&#xff08;RecurrentNeuralNetwork&#xff0c;RNN&#…

用算术右移实现逻辑右移及用逻辑右移实现算术右移

函数srl()用算术右移实现逻辑右移&#xff0c;函数sra()用逻辑右移实现算术右移。 程序代码 int sra(int x,int k); unsigned int srl(unsigned int x, int k);void main() {int rx1,k,x1;unsigned int rx2,x2;k3;x10x8777;x20x8777;rx1sra(x1, k);rx2srl(x2, k);while(1); }…