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

深入理解缓存穿透、缓存击穿和缓存雪崩

在现代分布式系统中,缓存是提升系统性能和减轻数据库负载的重要组件。然而,在实际应用中,我们可能会遇到一些缓存问题,如缓存穿透、缓存击穿和缓存雪崩。本文将详细探讨这三种缓存问题的原理、影响以及解决方案。

一,缓存穿透

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;}
}

四,总结

缓存穿透、缓存击穿和缓存雪崩是缓存系统中常见的问题。通过合理使用布隆过滤器、互斥锁、随机过期时间等技术手段,可以有效地解决这些问题,提升系统的稳定性和性能。在实际应用中,开发者应根据具体场景选择合适的解决方案,确保缓存系统的高效运行。

相关文章:

深入理解缓存穿透、缓存击穿和缓存雪崩

在现代分布式系统中&#xff0c;缓存是提升系统性能和减轻数据库负载的重要组件。然而&#xff0c;在实际应用中&#xff0c;我们可能会遇到一些缓存问题&#xff0c;如缓存穿透、缓存击穿和缓存雪崩。本文将详细探讨这三种缓存问题的原理、影响以及解决方案。 一&#xff0c;…...

【玩转动态规划专题】70. 爬楼梯【简单】

【玩转动态规划专题】70. 爬楼梯【简单】 1、力扣链接 https://leetcode.cn/problems/climbing-stairs/description/ 2、题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&…...

前端开发设计模式——组合模式

目录 一、组合模式的定义和特点 1.定义 2.特点&#xff1a; 二、组合模式的实现方式 1.定义抽象组件类 2.创建叶节点类 3.创建组合类&#xff1a; 三、组合模式的应用场景 1.界面布局管理 2.菜单系统构建 3.组件库开发 四、组合模式的优点 1.简化客户端代码 2.增…...

初探OceanBase 4.x单机环境下如何进行主备架构搭建

本文来自OceanBase 用户的体验分享 &#xff08;以下简称 OB&#xff09;&#xff0c;已经开源了3年左右&#xff0c;其间从3.x版本演进至4.x版本&#xff0c;发生了许多变化。对一个DBer而言&#xff0c;最为关切的是如何高效运用OB&#xff0c;以及是否能实现如同应用MySQL般…...

python 实现Edmonds-Karp算法

Edmonds-Karp算法介绍 Edmonds-Karp算法是一种用于解决最大流问题的算法&#xff0c;在计算机科学中广泛应用。以下是关于Edmonds-Karp算法的详细解释&#xff1a; 算法概述 Edmonds-Karp算法是基于Ford-Fulkerson方法的改进&#xff0c;它通过广度优先搜索&#xff08;BFS&…...

【牛客刷题实战】BC120 争夺前五名

大家好&#xff0c;我是小卡皮巴拉 文章目录 目录 牛客题目&#xff1a; BC120 争夺前五名 题目描述 输入描述&#xff1a; 输出描述&#xff1a; 示例1 示例2 解题思路&#xff1a; 具体思路&#xff1a; 题目要点&#xff1a; 完整代码&#xff1a; 兄弟们共…...

WMS 智慧仓储管理系统的可视化管理_SunWMS

【大家好&#xff0c;我是唐Sun&#xff0c;唐Sun的唐&#xff0c;唐Sun的Sun。一站式数智工厂解决方案服务商】 WMS 智慧仓储管理系统的可视化管理主要表现在以下几个方面&#xff1a; 首先是库存可视化。通过系统&#xff0c;仓库管理人员能够以直观的图表、图形等形式清晰地…...

动态代理代码示例

理解动态代理 动态代理的核心在于代理对象的创建和方法调用是在运行时动态发生的&#xff0c;而不是在编译时就已经确定的性能监控、事务管理、日志记录通常需要使用代理对象对目标对象的功能进行增强为什么JDK动态代理只能代理有接口的类&#xff1f; 因为Proxy.newProxyIns…...

SpringBoot+Activiti7工作流使用进阶实例-高亮显示BPMN流程图( SpringBoot+Activiti+mybatis+shiro实现)

文章目录 说明绘制流程图排他网关设置任务节点设置创建工程修改 pom.xml 文件准备数据库的表和测试数据修改 application.yml 文件配置静态资源Shiro 相关配置ShiroConfiguration.javaMyShiroRealm.java流程控制器添加静态的资源和模板页面运行结果截图源码地址说明 使用 Spri…...

C#使用Lazy<T>提高性能

以下是一些适合使用Lazy<T>的场景&#xff1a; 单例模式 在实现单例模式时&#xff0c;Lazy<T>是非常有用的。如前面提到的示例&#xff0c;它可以确保单例对象在首次被访问时才进行创建&#xff0c;同时在多线程环境下也能保证正确的行为。这种方式比传统的双重检…...

创建读取比特币1P类型地址

创建读取比特币1P类型地址 比特币的地址类型有多种&#xff0c;其中 P2TR&#xff08;Pay-to-Taproot&#xff09;地址是基于最近的升级&#xff08;Taproot&#xff09;引入的一个新类型。本文将介绍如何创建和读取比特币的 1P 类型地址&#xff0c;主要通过 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耐环境伺服驱动器 极端环境下高精度控制解决方案

全球工业环境的日益复杂多变&#xff0c;对伺服驱动器的要求不再局限于基本的性能参数&#xff0c;而是在极端环境下的稳定性与可靠性。Copley耐环境伺服驱动器以卓越的性能和出色的环境适应性&#xff0c;为工业自动化领域的高精度控制提供了可靠的解决方案。 一、多样化的产…...

前端的全栈混合之路Meteor篇:分布式数据协议DDP深度剖析

本文属于进阶篇&#xff0c;并不是太适合新人阅读&#xff0c;但纯粹的学习还是可以的&#xff0c;因为后续会实现很多个ddp的版本用于web端、nodejs端、安卓端和ios端&#xff0c;提前预习和复习下。ddp协议是一个C/S架构的协议&#xff0c;但是客户端也同时可以是服务端。 什…...

基于Zynq SDIO WiFi移植一(支持2.4/5G)

基于SDIO接口的WIFI&#xff0c;在应用上&#xff0c;功耗低于USB接口&#xff0c;且无须USB Device支持&#xff0c;满足某些应用场景 1 硬件连接 2 Vivado工程配置 3 驱动编译 3.1 KERNRL CONFIG (build ENV) 修改 export KERNELPATH<path of kernel header>export T…...

数据结构与算法篇(刷题篇 - 链表)

目录 1. 反转链表&#xff08;简单&#xff09; 1.1. 题目描述 1.2. 解题思路 方法一&#xff1a;迭代&#xff08;推荐使用&#xff09; 方法二&#xff1a;递归&#xff08;扩展思路&#xff09; 方法三&#xff1a;使用栈解决 方法四&#xff1a;双链表求解 2. 链表内…...

TinyAgent: 从零开始构建最小化Agent系统

引言 随着大模型&#xff08;LLM&#xff09;的崛起&#xff0c;特别是ChatGPT等大模型的广泛应用&#xff0c;基于LLM的系统越来越受欢迎。然而&#xff0c;尽管大模型具备强大的生成能力和推理能力&#xff0c;它们在处理某些专有领域或实时问题时仍然存在局限性。因此&#…...

Android Studio New里面没有New Flutter Project

跟着Flutter中文网的配置教程&#xff0c;安装好了flutter,在Android studio里面也安装了dart和flutter的插件。重启后还是在FIle->New里面没有显示New Flutter Project。 反复卸载重装dart和flutter插件好几次&#xff0c;依然没有效果。 原来是没有把Android APK Suppor…...

linux信号 | 学习信号四步走 | 透析信号是如何被处理的?

前言&#xff1a;本节内容讲述linux信号的捕捉。 我们通过前面的学习&#xff0c; 已经学习了信号的概念&#xff0c; 信号的产生&#xff0c; 信号的保存。 只剩下信号的处理。 而信号的处理我们应该着重注意的是第三种处理方式——信号的捕捉。 也就是说&#xff0c; 这篇文章…...

mysql语句执行过程

具体流程如下: 1】当客户端的SOL发送到MySQL时&#xff0c;首先是到达服务器层的连接器&#xff0c;连接器会对你此次发起的连接进行权限校验&#xff0c;以此来获取你这个账号拥有的权限。当你的账号或密码不正确时&#xff0c;会报用户错误。连接成功如果后续没有任何操作&am…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

安卓基础(Java 和 Gradle 版本)

1. 设置项目的 JDK 版本 方法1&#xff1a;通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分&#xff0c;设置 Gradle JDK 方法2&#xff1a;通过 Settings File → Settings... (或 CtrlAltS)…...