深入理解缓存穿透、缓存击穿和缓存雪崩
在现代分布式系统中,缓存是提升系统性能和减轻数据库负载的重要组件。然而,在实际应用中,我们可能会遇到一些缓存问题,如缓存穿透、缓存击穿和缓存雪崩。本文将详细探讨这三种缓存问题的原理、影响以及解决方案。
一,缓存穿透
1. 原理
缓存穿透是指缓存和数据库中都不存在的数据被频繁请求,导致每次请求都要到数据库去查询,从而失去了缓存的意义。这通常是由于恶意攻击或程序错误引起的。

2. 影响
缓存穿透会直接导致数据库压力增大,严重时可能导致数据库崩溃。
3. 解决方案
- 布隆过滤器(Bloom Filter): 在缓存之前增加一个布隆过滤器,用于快速判断请求的数据是否存在。如果布隆过滤器判断数据不存在,则直接返回,而不访问数据库。
- 缓存空结果: 对于查询结果为空的数据,可以将空结果也缓存起来,并设置一个较短的过期时间,防止同一请求频繁访问数据库。
- 非法值校验: 对于一些请求参数,我们是能够判断出是否合法,如果不合法直接在入口处拦截,自然不需要穿透到 DB。
4. 示例代码
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;public class CacheService {private static BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(), 100000);public String getData(String key) {if (!bloomFilter.mightContain(key)) {return null; // 数据不存在}String value = redis.get(key);if (value == null) {value = database.get(key);if (value != null) {redis.set(key, value);} else {redis.set(key, "null", 60); // 缓存空结果}}return value;}
}
二, 缓存击穿
1. 原理
缓存击穿是指某些热点数据在缓存过期的瞬间,有大量请求同时到达,导致这些请求直接访问数据库,造成数据库压力骤增。
2. 影响
缓存击穿会导致数据库在短时间内承受大量请求,可能会引发数据库性能问题。
3. 解决方案
- 互斥锁(Mutex): 在缓存失效时,使用互斥锁来控制只有一个线程能访问数据库,其他线程等待缓存更新完成。
- 提前更新缓存: 设置热点数据的缓存不过期,或者在缓存即将过期时主动更新缓存。
4. 示例代码
import java.util.concurrent.locks.ReentrantLock;public class CacheService {private ReentrantLock lock = new ReentrantLock();public String getData(String key) {String value = redis.get(key);if (value == null) {lock.lock();try {value = redis.get(key);if (value == null) {value = database.get(key);if (value != null) {redis.set(key, value);}}} finally {lock.unlock();}}return value;}
}
三,缓存雪崩
1. 原理
缓存雪崩是指在某一个时间段内,大量缓存同时失效,导致大量请求直接访问数据库,造成数据库压力骤增。

2. 影响
缓存雪崩会导致数据库在短时间内承受巨大的压力,可能会引发系统崩溃。
3. 解决方案
- 缓存过期时间分散: 设置缓存时,使用随机的过期时间,避免大量缓存同时失效。
- 双缓存策略: (Redis 高可用)使用主缓存和备份缓存,当主缓存失效时,从备份缓存中读取数据。
- 限流降级: 在缓存失效时,对请求进行限流或降级处理,防止数据库被压垮。
- 数据库解耦: 应用完全与数据库解耦,只读 Redis,由专门的 job 应用主动填充缓存。
4. 示例代码
import java.util.Random;public class CacheService {private Random random = new Random();public void setData(String key, String value) {int expireTime = 3600 + random.nextInt(600); // 随机过期时间redis.set(key, value, expireTime);}public String getData(String key) {String value = redis.get(key);if (value == null) {value = database.get(key);if (value != null) {setData(key, value);}}return value;}
}
四,总结
缓存穿透、缓存击穿和缓存雪崩是缓存系统中常见的问题。通过合理使用布隆过滤器、互斥锁、随机过期时间等技术手段,可以有效地解决这些问题,提升系统的稳定性和性能。在实际应用中,开发者应根据具体场景选择合适的解决方案,确保缓存系统的高效运行。
相关文章:
深入理解缓存穿透、缓存击穿和缓存雪崩
在现代分布式系统中,缓存是提升系统性能和减轻数据库负载的重要组件。然而,在实际应用中,我们可能会遇到一些缓存问题,如缓存穿透、缓存击穿和缓存雪崩。本文将详细探讨这三种缓存问题的原理、影响以及解决方案。 一,…...
【玩转动态规划专题】70. 爬楼梯【简单】
【玩转动态规划专题】70. 爬楼梯【简单】 1、力扣链接 https://leetcode.cn/problems/climbing-stairs/description/ 2、题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 1&…...
前端开发设计模式——组合模式
目录 一、组合模式的定义和特点 1.定义 2.特点: 二、组合模式的实现方式 1.定义抽象组件类 2.创建叶节点类 3.创建组合类: 三、组合模式的应用场景 1.界面布局管理 2.菜单系统构建 3.组件库开发 四、组合模式的优点 1.简化客户端代码 2.增…...
初探OceanBase 4.x单机环境下如何进行主备架构搭建
本文来自OceanBase 用户的体验分享 (以下简称 OB),已经开源了3年左右,其间从3.x版本演进至4.x版本,发生了许多变化。对一个DBer而言,最为关切的是如何高效运用OB,以及是否能实现如同应用MySQL般…...
python 实现Edmonds-Karp算法
Edmonds-Karp算法介绍 Edmonds-Karp算法是一种用于解决最大流问题的算法,在计算机科学中广泛应用。以下是关于Edmonds-Karp算法的详细解释: 算法概述 Edmonds-Karp算法是基于Ford-Fulkerson方法的改进,它通过广度优先搜索(BFS&…...
【牛客刷题实战】BC120 争夺前五名
大家好,我是小卡皮巴拉 文章目录 目录 牛客题目: BC120 争夺前五名 题目描述 输入描述: 输出描述: 示例1 示例2 解题思路: 具体思路: 题目要点: 完整代码: 兄弟们共…...
WMS 智慧仓储管理系统的可视化管理_SunWMS
【大家好,我是唐Sun,唐Sun的唐,唐Sun的Sun。一站式数智工厂解决方案服务商】 WMS 智慧仓储管理系统的可视化管理主要表现在以下几个方面: 首先是库存可视化。通过系统,仓库管理人员能够以直观的图表、图形等形式清晰地…...
动态代理代码示例
理解动态代理 动态代理的核心在于代理对象的创建和方法调用是在运行时动态发生的,而不是在编译时就已经确定的性能监控、事务管理、日志记录通常需要使用代理对象对目标对象的功能进行增强为什么JDK动态代理只能代理有接口的类? 因为Proxy.newProxyIns…...
SpringBoot+Activiti7工作流使用进阶实例-高亮显示BPMN流程图( SpringBoot+Activiti+mybatis+shiro实现)
文章目录 说明绘制流程图排他网关设置任务节点设置创建工程修改 pom.xml 文件准备数据库的表和测试数据修改 application.yml 文件配置静态资源Shiro 相关配置ShiroConfiguration.javaMyShiroRealm.java流程控制器添加静态的资源和模板页面运行结果截图源码地址说明 使用 Spri…...
C#使用Lazy<T>提高性能
以下是一些适合使用Lazy<T>的场景: 单例模式 在实现单例模式时,Lazy<T>是非常有用的。如前面提到的示例,它可以确保单例对象在首次被访问时才进行创建,同时在多线程环境下也能保证正确的行为。这种方式比传统的双重检…...
创建读取比特币1P类型地址
创建读取比特币1P类型地址 比特币的地址类型有多种,其中 P2TR(Pay-to-Taproot)地址是基于最近的升级(Taproot)引入的一个新类型。本文将介绍如何创建和读取比特币的 1P 类型地址,主要通过 JavaScript 和相…...
从零开始Hadoop集群环境搭建
目录 1. Centos7.5硬件配置1.1 创建虚拟机1.2 虚拟机系统设置 2. IP地址和主机名称配置3. 软件配置3.1 安装 epel-release3.2 卸载虚拟机自带的JDK3.3 克隆虚拟机3.4 修改克隆虚拟机的IP3.5 JDK安装3.6 Hadoop安装 4. Hadoop目录结构 1. Centos7.5硬件配置 1.1 创建虚拟机 1.2…...
Copley耐环境伺服驱动器 极端环境下高精度控制解决方案
全球工业环境的日益复杂多变,对伺服驱动器的要求不再局限于基本的性能参数,而是在极端环境下的稳定性与可靠性。Copley耐环境伺服驱动器以卓越的性能和出色的环境适应性,为工业自动化领域的高精度控制提供了可靠的解决方案。 一、多样化的产…...
前端的全栈混合之路Meteor篇:分布式数据协议DDP深度剖析
本文属于进阶篇,并不是太适合新人阅读,但纯粹的学习还是可以的,因为后续会实现很多个ddp的版本用于web端、nodejs端、安卓端和ios端,提前预习和复习下。ddp协议是一个C/S架构的协议,但是客户端也同时可以是服务端。 什…...
基于Zynq SDIO WiFi移植一(支持2.4/5G)
基于SDIO接口的WIFI,在应用上,功耗低于USB接口,且无须USB Device支持,满足某些应用场景 1 硬件连接 2 Vivado工程配置 3 驱动编译 3.1 KERNRL CONFIG (build ENV) 修改 export KERNELPATH<path of kernel header>export T…...
数据结构与算法篇(刷题篇 - 链表)
目录 1. 反转链表(简单) 1.1. 题目描述 1.2. 解题思路 方法一:迭代(推荐使用) 方法二:递归(扩展思路) 方法三:使用栈解决 方法四:双链表求解 2. 链表内…...
TinyAgent: 从零开始构建最小化Agent系统
引言 随着大模型(LLM)的崛起,特别是ChatGPT等大模型的广泛应用,基于LLM的系统越来越受欢迎。然而,尽管大模型具备强大的生成能力和推理能力,它们在处理某些专有领域或实时问题时仍然存在局限性。因此&#…...
Android Studio New里面没有New Flutter Project
跟着Flutter中文网的配置教程,安装好了flutter,在Android studio里面也安装了dart和flutter的插件。重启后还是在FIle->New里面没有显示New Flutter Project。 反复卸载重装dart和flutter插件好几次,依然没有效果。 原来是没有把Android APK Suppor…...
linux信号 | 学习信号四步走 | 透析信号是如何被处理的?
前言:本节内容讲述linux信号的捕捉。 我们通过前面的学习, 已经学习了信号的概念, 信号的产生, 信号的保存。 只剩下信号的处理。 而信号的处理我们应该着重注意的是第三种处理方式——信号的捕捉。 也就是说, 这篇文章…...
mysql语句执行过程
具体流程如下: 1】当客户端的SOL发送到MySQL时,首先是到达服务器层的连接器,连接器会对你此次发起的连接进行权限校验,以此来获取你这个账号拥有的权限。当你的账号或密码不正确时,会报用户错误。连接成功如果后续没有任何操作&am…...
3个核心功能让Notepad++成为你的Markdown高效编辑器
3个核心功能让Notepad成为你的Markdown高效编辑器 【免费下载链接】MarkdownViewerPlusPlus A Notepad Plugin to view a Markdown file rendered on-the-fly 项目地址: https://gitcode.com/gh_mirrors/ma/MarkdownViewerPlusPlus 你是否曾经在Notepad中编写Markdown文…...
Tauri + GitHub Actions 自动化打包指南:如何为你的桌面应用配置跨平台自动更新
Tauri GitHub Actions 自动化打包与更新体系构建指南 当你的Tauri应用从开发阶段进入产品化阶段时,如何确保用户能够无缝获取最新功能和安全更新,成为影响产品体验的关键因素。本文将带你构建一个完整的自动化打包与更新体系,从签名机制到发…...
从HC595到TM1637:一个STM32新手解决数码管闪烁的踩坑实录
从HC595到TM1637:一个STM32新手解决数码管闪烁的踩坑实录 数码管作为嵌入式开发中最基础的显示器件之一,其驱动方式的选择往往决定了整个系统的稳定性和用户体验。当我在一个温湿度监测项目中首次使用HC595驱动四位数码管时,完全没有预料到会…...
优惠电影票API接口,7折电影起步
请求参数说明store_idint是1店铺idshowIdstring是没下划线那个showid场次ID返回参数说明codestring00000000代表成功msgstring获取成功获取成功timestring1639640142时间戳dataobject[]infoobject[]影片信息idstring2film_idstring...
为什么92%的DeepSeek AWS部署失败?资深架构师拆解3大隐性成本陷阱与4步合规加固法
更多请点击: https://codechina.net 第一章:DeepSeek AWS部署教程 在AWS云平台上部署DeepSeek系列大语言模型(如DeepSeek-V2、DeepSeek-Coder)需兼顾计算性能、存储效率与网络低延迟。推荐使用g5.12xlarge或p4d.24xlarge实例类型…...
电脑突然‘哑巴’了?保姆级排查指南:从服务、驱动到系统修复,一步步搞定Win10音频问题
电脑突然‘哑巴’了?保姆级排查指南:从服务、驱动到系统修复,一步步搞定Win10音频问题 右下角的小喇叭突然打上红叉,视频会议开到一半突然失声,游戏打到关键处却没了音效——这些场景恐怕每个Windows 10用户都遭遇过。…...
STM32 ADC实战避坑:轮询、中断、DMA到底怎么选?我的项目血泪经验
STM32 ADC实战避坑:轮询、中断、DMA到底怎么选?我的项目血泪经验 在嵌入式开发中,ADC(模数转换器)是连接模拟世界与数字世界的关键桥梁。无论是电池电压监测、环境光传感还是工业控制中的各种模拟量采集,AD…...
CANN/hcomm集群信息初始化API
HcclCommInitClusterInfo 【免费下载链接】hcomm HCOMM(Huawei Communication)是HCCL的通信基础库,提供通信域以及通信资源的管理能力。 项目地址: https://gitcode.com/cann/hcomm 产品支持情况 Ascend 950PR/Ascend 950DT࿱…...
联想RD450X服务器风扇策略深度解析:IPMI raw命令详解与安全调校指南
联想RD450X服务器IPMI风扇调校实战:从底层指令到安全优化 在数据中心密集部署的服务器集群中,散热管理往往成为平衡性能与可靠性的关键支点。联想RD450X作为主流2U机架式服务器,其智能风扇控制系统通过IPMI接口提供了丰富的底层调节能力&…...
从零开始:YY3568开发板刷写原生Linux系统全流程指南
1. 项目概述与核心价值 最近拿到了一块YY3568开发板,这是一款基于瑞芯微RK3568芯片的嵌入式开发平台,性能相当不错。很多朋友拿到开发板后,第一反应就是跟着官方文档跑个Demo,或者直接用板子预装的Android系统。但如果你和我一样&…...
