深度剖析缓存相关问题:雪崩、穿透、预热、更新、降级

目录

引言

1. 缓存雪崩

1.1 问题描述

1.2 解决方案

1.2.1 加锁防止并发重建缓存

2. 缓存穿透

2.1 问题描述

2.2 解决方案

2.2.1 布隆过滤器防止无效请求

3. 缓存预热

3.1 问题描述

3.2 分析与解决方案

3.2.1 定时任务预热缓存

4. 缓存更新

4.1 问题描述

4.2 分析与解决方案

4.2.1 主动更新缓存

5. 缓存降级

5.1 问题描述

5.2 分析与解决方案

5.2.1 降级机制提供默认值

总结

祝屏幕前的你,好运不断!


引言

在系统开发中,缓存是提升性能和降低数据库负载的重要手段。然而,缓存并非没有问题,常见的问题包括缓存雪崩、缓存穿透、缓存预热、缓存更新和缓存降级等。本文将详细分析这些缓存相关的问题,并提供解决方案。

1. 缓存雪崩

1.1 问题描述

       缓存雪崩是指在缓存中的大量数据同时过期或失效,导致大量请求直接落到数据库,压力剧增,可能导致系统崩溃。我们可以简单的理解为:由于原有缓存失效,新缓存未到期间 (例如:我们设置缓存时采用了相同的过期时间,在同一时刻出现大面积的缓存过期),所有原本应该访问缓存的请求都去查询数据库了,而对数据库CPU和内存造成巨大压力,严重的会造成数据库宕机。从而形成一系列连锁反应,造成整个系统崩溃。

1.2 解决方案

1.2.1 加锁防止并发重建缓存
public class CacheService {private final Object lock = new Object();public Object getData(String key) {Object data = getFromCache(key);if (data == null) {synchronized (lock) {data = getFromCache(key);if (data == null) {data = getFromDatabase(key);putIntoCache(key, data);}}}return data;}// 其他业务逻辑...
}

2. 缓存穿透

2.1 问题描述

        缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询)。这样请求就绕过缓存直接查数据库,这也是经常提的缓存命中率问题。

2.2 解决方案

2.2.1 布隆过滤器防止无效请求
public class CacheService {private final BloomFilter<String> bloomFilter = new BloomFilter<>();public Object getData(String key) {if (!bloomFilter.mightContain(key)) {return null;}Object data = getFromCache(key);if (data == null) {data = getFromDatabase(key);putIntoCache(key, data);}return data;}// 其他业务逻辑...
}

3. 缓存预热

3.1 问题描述

      缓存预热是指在系统上线或重启后,将部分或全部数据预先加载到缓存中,防止大量请求直接访问数据库。

3.2 分析与解决方案

3.2.1 定时任务预热缓存

通过定时任务,在系统启动或每天凌晨1点等时机,将需要预热的数据加载到缓存中:

@Component
public class CacheWarmUpTask {@Autowiredprivate CacheService cacheService;@Scheduled(cron = "0 0 1 * * ?") // 每天凌晨1点执行public void warmUpCache() {List<String> keysToWarmUp = getKeysToWarmUp();for (String key : keysToWarmUp) {cacheService.getData(key);}}private List<String> getKeysToWarmUp() {// 根据业务逻辑获取需要预热的缓存键列表// ...}
}

4. 缓存更新

4.1 问题描述

缓存更新是指数据库中的数据更新后,及时将缓存中的数据进行同步。

4.2 分析与解决方案

4.2.1 主动更新缓存

        除了缓存服务器自带的缓存失效策略之外(Redis默认的有6中策略可供选择),我们还可以根据具体的业务需求进行自定义的缓存淘汰,常见的策略有两种: (1)定时去清理过期的缓存; (2)当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存。 两者各有优劣,第一种的缺点是维护大量缓存的key是比较麻烦的,第二种的缺点就是每次用户请求过来都要判断缓存失效,逻辑相对比较复杂!具体用哪种方案,大家可以根据自己的应用场景来权衡。

public class CacheService {public void updateCache(String key, Object newData) {// 更新缓存putIntoCache(key, newData);}// 其他业务逻辑...
}

5. 缓存降级

5.1 问题描述

       缓存降级是指在系统遇到异常或缓存失效的情况下,通过某种方式提供默认值或兜底数据,保证系统正常运行。

       当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。 降级的最终目的是保证核心服务可用,即使是有损的而且有些服务是无法降级的(如加入购物车、结算)。 以参考日志级别设置预案: (1)一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级; (2)警告:有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级,并发送告警; (3)错误:比如可用率低于90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阀值,此时可以根据情况自动降级或者人工降级; (4)严重错误:比如因为特殊原因数据错误了,此时需要紧急人工降级。服务降级的目的,是为了防止Redis服务故障,导致数据库跟着一起发生雪崩问题。因此,对于不重要的缓存数据,可以采取服务降级策略,例如一个比较常见的做法就是Redis出现问题,不去数据库查询,而是直接返回默认值给用户。

5.2 分析与解决方案

5.2.1 降级机制提供默认值

在缓存失效或异常时,提供默认值或兜底数据,确保系统正常运行:

public class CacheService {public Object getData(String key) {Object data = getFromCache(key);if (data == null) {data = getFromDatabase(key);if (data != null) {putIntoCache(key, data);} else {data = getDefaultData();}}return data;}private Object getDefaultData() {// 提供默认值或兜底数据// ...}// 其他业务逻辑...
}

总结

       通过深入分析缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题,并提供相应的解决方案,可以有效提高系统的稳定性和性能。在实际应用中,应根据业务场景选择合适的方案,综合考虑多方面因素,以保障系统的高可用性和稳定性。长文分析力求全面,希望能为读者提供深度的理解和实践指导。

祝屏幕前的你,好运不断!

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

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

相关文章

华为端口安全常用3种方法配置案例

安全动态mac地址学习功能 [Huawei]int g0/0/01 interface GigabitEthernet0/0/1 port-security enable //开启安全 port-security max-mac-num 2 //最多为2个mac地址学习 port-security protect-action restrict //丢包带警告 port-security aging-time 1 //mac地址的老化时间…

C/C++ 堆排序

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a;数据结构_仍有未知等待探索的博客-CSDN博客 欢迎大家来指教&#xff01; 一、前言 今天要介绍的是堆排序。 首先什么是堆&#xff1f;简而言之&#xff0c;堆就是二叉树的数组形式&#xff0c;用数组来存…

css3边框与圆角

css3边框与圆角 前言边框的三要素边框的三要素小属性 四个方向的边框四个方向边框的三要素小属性 去掉边框利用边框制作三角形圆角 border-radius单独设置四个圆角小属性百分比为单位 盒子阴影阴影延展内阴影多阴影 结语 前言 在网页设计中&#xff0c;边框与圆角不仅仅是简单…

邂逅Node.JS的那一夜

邂逅Node.JS的那一夜&#x1f303; 本篇文章&#xff0c;学习记录于&#xff1a;尚硅谷&#x1f3a2; 本篇文章&#xff0c;并不完全适合小白&#xff0c;需要有一定的HTML、CSS、JS、HTTP、Web等知识及基础学习&#xff1a; &#x1f197;&#xff0c;紧接上文&#xff0c;…

uⅤ打印-小理光上海RYPC后台运动系统

uⅤ打印-小理光上海RYPC后台运动系统

ISO 11519-2 开环低速 CAN 网络(10K~125Kbps)

ISO 11519-2 标准的物理框图如下图 可理解为一个低速开环 CAN 总线网络&#xff1b;CAN 开环总线网络允许总线最大长度为 1km;最高速度为 125Kbps;这里的两根线是独立的&#xff0c;每根线上串联一个 2.2kΩ 的电阻&#xff1b;节点就是不同的设备&#xff0c;连接到一个开环总…

【微服务】日志搜集es+kibana+filebeat+redis+logstash(单机)

日志搜集系统搭建 基于7.17.16版本 ps: 项目是toB的&#xff0c;日志量不大 前置准备 软件下载 7.17.16版本。8.x版本需要JDK11 elastic.co/downloads/past-releasesJDK java8 Linux elastic 软件不能以root用户启动&#xff0c;需要创建用户 sudo useradd elastic #给此…

解决:ModuleNotFoundError: No module named ‘pymysql’

解决&#xff1a;ModuleNotFoundError: No module named ‘pymysql’ 文章目录 解决&#xff1a;ModuleNotFoundError: No module named pymysql背景报错问题报错翻译报错位置代码报错原因解决方法方法一&#xff0c;直接安装方法二&#xff0c;手动下载安装方法三&#xff0c;…

云贝教育 |【技术文章】存储对象的LIBRARY CACHE LOCK/PIN实验(一)

注: 本文为云贝教育 刘峰 原创&#xff0c;请尊重知识产权&#xff0c;转发请注明出处&#xff0c;不接受任何抄袭、演绎和未经注明出处的转载。 实验环境 操作系统&#xff1a;Red Hat Enterprise Linux release 8.8 (Ootpa) 数据库&#xff1a;oracle Version 19.3.0.0.0 …

UE 引擎工具笔记

2023虚幻技术分享会视频 1.2023年虚幻引擎最新功能和技巧 [UFSH2023]2023年虚幻引擎最新功能和技巧 | Chris Murphy Epic Games_哔哩哔哩_bilibili 推荐细看下.总结了UE5的功能大概 2.调试技巧 [UFSH2023]总有一个你不知道的虚幻引擎调试技巧 | 陈拓 Epic Games_哔哩哔哩_…

深信服态势感知一体机SIP-1000 Y2100 3.0.1Y升级3.0.3Y步骤

当前版本&#xff1a;3.0.1Y 升级后版本&#xff1a;3.0.3Y PS&#xff1a;3.0.1Y不能直升3.0.3Y&#xff0c;需要先通过升级工具升级到3.0.2Y&#xff0c;再安装前置补丁从3.0.2Y升级到3.0.3Y&#xff1b;每一次升级时间为20-30分钟&#xff0c;设备升级会重启&#xff0c;需提…

计算机网络-VLAN间通信

之前复习了VLAN的概念以及几个接口类型。VLAN在二层可以实现广播域的划分&#xff0c;VLAN间可以实现二层通信&#xff0c;但是不能实现三层通信&#xff0c;需要借助其它方式。 一、概述 实际网络部署中一般会将不同IP地址段划分到不同的VLAN。同VLAN且同网段的PC之间可直接进…

2023 Gartner® 云数据库管理系统魔力象限发布 PingCAP 入选“荣誉提及”

近日&#xff0c;全球 IT 市场研究和咨询 公司 Gartner 发布最新报告《Magic Quadrant™ for Cloud Database Management Systems》&#xff08;云数据库管理系统魔力象限&#xff09;&#xff0c; 企业级开源分布式数据库厂商 PingCAP 入选“荣誉提及” 。前不久&#xff0c;P…

GENMARK控制器维修SMALL SMC4092

晶圆转移机器人SMALL CONTROLLER控制器维修 SMC1100 半导体设备机械臂GENMARK控制器维修 eSensor特点&#xff1a; &#xff08;1&#xff09;基于DNA杂交和电化学检测原理&#xff1b; &#xff08;2&#xff09;电化学传感检测&#xff0c;并非荧光或光学检测。 电子信号的…

查准率与查全率在自然语言处理中的核心概念与联系、核心概念和实践应用,如何使用朴素贝叶斯、SVM 和深度学习实现查准率和查全率的计算?

查准率与查全率在自然语言处理中的核心概念与联系、核心概念和实践应用,如何使用朴素贝叶斯、SVM 和深度学习实现查准率和查全率的计算? 人工智能核心技术有:1. 深度学习;2.计算机视觉;3.自然语言处理;4.数据挖掘。其中,深度学习就是使用算法分析数据,从中学习并自动归…

开源免费虚拟化KVM的部署及其虚拟机资源变更、快照、克隆等常见运维操作

实践说明&#xff1a;基于RHEL9(AlmaLinux9.1)部署&#xff0c;同类系统(CentOS9,RockyLinux9等)适用&#xff0c;但适用场景是不限于此的。 文档说明&#xff1a;本文档旨在帮助快速应用KVM虚拟化技术&#xff0c;重在实践操作&#xff0c;提供了简要参考。 文档形成时期&…

【Oracle】数据库查询与SQL语句

Oracle查询 一、单表查询 1、简单条件查询 1&#xff09;精确查询 SELECT* FROMT_OWNERS WHEREwatermeter 304082&#xff09;模糊查询 SELECT* FROMt_owners WHEREname LIKE %刘%3&#xff09;and运算符 SELECT* FROMt_owners WHEREname LIKE %刘% AND housenumb…

HTML--文本

文本一般存在于 body下 段落标签&#xff1a;<p> </p> 换行标签&#xff1a;<br/> 放在一句话里可以换行 <p>这是一段话<br/>这是另一段话</p>文本标签分以下几种&#xff1a; 粗体标签&#xff1a;strong&#xff0c;b 斜体标签&#xf…

postgresql 流复制相关参数及影响

修改流复制相关的参数&#xff0c;测试影响 wal_level wal日志级别&#xff0c;这个参数决定了有多少信息写入wal日志&#xff0c;默认是replica。&#xff08;TDSQL-PG 默认是 logical minimal&#xff1a;除了实例crash恢复需要的记录&#xff0c;其他不记录&#xff0c;比…

VUE+bpmn.js实现工作流

1、安装bpmn.js npm install bpmn-js7.3.1 // 我安装的版本是7.3.1npm install bpmn-js-properties-panel0.37.2npm install bpmn-moddle7.1.3 npm install --save camunda-bpmn-moddle 2、配置axios&#xff0c;在main.js中引入axios import axios from axiosVue.proto…