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

Redis 缓存雪崩、缓存穿透、缓存击穿详解

缓存雪崩

缓存雪崩指的是大量缓存数据在同一时间失效,导致所有请求直接打到数据库或下游系统,造成数据库瞬时压力剧增,甚至可能引发系统崩溃。

形成原因:

  • 缓存数据同时过期:由于缓存过期时间设置不合理,导致大量缓存同时失效,所有请求直接落到数据库。
  • 缓存服务器宕机:缓存服务本身发生故障,无法响应请求,所有请求直接到数据库。

假设你有一个热门商品页面,所有缓存的商品数据过期时间相同,比如都设定为 12 小时。当 12 小时一到,所有缓存失效,用户请求打到数据库,数据库承受巨大压力,甚至可能导致崩溃。

缓存雪崩的避免方案

缓存过期时间设置随机化

为每个缓存的键设置不同的过期时间,避免大批量缓存同时失效。可以在原有过期时间的基础上,添加一个随机值(如 1-5 分钟的随机过期时间)。

缓存雪崩的解决方案

1. 限流降级

在发生缓存雪崩时,使用限流机制,限制进入数据库的请求数量。同时可以启用降级策略,例如返回默认数据或空数据来保证系统的可用性。

2. 缓存预热

在系统启动或缓存即将过期时,提前加载常用的数据到缓存中,避免缓存失效后瞬间打爆数据库。这种方式可以通过定时任务来实现。

缓存穿透

缓存穿透 指的是用户请求的数据根本不在缓存和数据库中,导致每次请求都直接查询数据库。即使我们把不存在的数据存入缓存,依然没有命中缓存,从而让缓存失效。

形成原因:

  • 用户恶意请求一些不存在的数据,缓存中没有,数据库也查不到,每次查询都打到数据库,造成数据库负载过大。

如果用户不断请求数据库中不存在的 id,比如负数 id=-1 或很大范围的 id 值,而系统没有处理此类非法请求,导致这些请求每次都穿过缓存直达数据库。

缓存穿透的解决方案

1. 使用布隆过滤器

布隆过滤器(Bloom Filter)是一种空间高效的概率性数据结构,可以快速判断某个数据是否存在。对于不存在的请求,在查询数据库之前先通过布隆过滤器检查是否有该记录,避免穿透到数据库。

2. 缓存空对象

对于查询结果为 null 的数据,直接缓存一个空值,并设置较短的过期时间(如 5 分钟),避免短时间内重复查询这些不存在的数据。

缓存击穿

缓存击穿 指的是某个热点数据在缓存失效的瞬间,有大量并发请求同时到达这个数据,由于缓存过期,这些请求直接打到数据库,导致数据库负载激增。

形成原因:

  • 某些热门数据(热点 key)过期时间到达,但此时有大量并发请求请求这个数据,由于缓存失效,所有请求都会查询数据库,形成短时间内的高并发。

假设你有一个热门商品 id=100 的缓存,在缓存失效时(比如设定 5 分钟后过期),恰好有成千上万的用户访问这个商品。由于缓存失效,所有请求都会同时打到数据库,造成数据库压力激增。

缓存击穿的解决方案

1、缓存热点数据

对于热点数据,可以设置较长的过期时间,或者让这些数据不过期,定期主动更新缓存,避免过期时产生缓存击穿。

2、使用互斥锁(分布式锁)

在缓存失效的瞬间,为第一个请求的线程加锁,只有获取到锁的线程可以访问数据库并更新缓存,其他线程等待缓存更新后再读取缓存,避免数据库被并发请求打爆。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 2024年中国研究生数学建模竞赛C题——解题思路
  • 【已解决】Linux ubuntu 20.04 docker 不需要sudo权限
  • 机器视觉OpenCV
  • 【系统架构设计师】专题:特定领域软件架构 DSSA(详细知识点及历年真题)
  • ER 图 Entity-Relationship (ER) diagram 101 电子商城 数据库设计
  • Cisco 基础网络汇总
  • 【机器学习】任务五:葡萄酒和鸢尾花数据集分类任务
  • Docker UI强大之处?
  • 《SmartX ELF 虚拟化核心功能集》发布,详解 80+ 功能特性和 6 例金融实践
  • 无人机集群路径规划:​北方苍鹰优化算法(Northern Goshawk Optimization,NGO)​求解无人机集群路径规划,提供MATLAB代码
  • Nginx:高性能Web服务器与反向代理的深度解析
  • AI+教育|拥抱AI智能科技,让课堂更生动高效
  • 浙版传媒思迈特软件大数据分析管理平台建设项目正式启动
  • 13年计算机考研408-数据结构
  • 信息安全工程师(12)网络攻击概述
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • CEF与代理
  • Effective Java 笔记(一)
  • iOS 颜色设置看我就够了
  • IOS评论框不贴底(ios12新bug)
  • Java编程基础24——递归练习
  • Java应用性能调优
  • Median of Two Sorted Arrays
  • Odoo domain写法及运用
  • Puppeteer:浏览器控制器
  • spring + angular 实现导出excel
  • Yii源码解读-服务定位器(Service Locator)
  • 每个JavaScript开发人员应阅读的书【1】 - JavaScript: The Good Parts
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 前嗅ForeSpider中数据浏览界面介绍
  • 吴恩达Deep Learning课程练习题参考答案——R语言版
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • - 转 Ext2.0 form使用实例
  • 从如何停掉 Promise 链说起
  • ​iOS实时查看App运行日志
  • !!java web学习笔记(一到五)
  • # Kafka_深入探秘者(2):kafka 生产者
  • (2)(2.10) LTM telemetry
  • (k8s)kubernetes集群基于Containerd部署
  • (STM32笔记)九、RCC时钟树与时钟 第二部分
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (删)Java线程同步实现一:synchronzied和wait()/notify()
  • (算法)硬币问题
  • (转)c++ std::pair 与 std::make
  • ***检测工具之RKHunter AIDE
  • .NET 4.0中使用内存映射文件实现进程通讯
  • .NET Remoting学习笔记(三)信道
  • .NET技术成长路线架构图
  • .NET教程 - 字符串 编码 正则表达式(String Encoding Regular Express)
  • .NET命令行(CLI)常用命令
  • .NET命名规范和开发约定
  • .Net中ListT 泛型转成DataTable、DataSet
  • /etc/apt/sources.list 和 /etc/apt/sources.list.d