Reids缓存穿透、缓存雪崩和缓存击穿

Redis缓存中常见的三个问题:缓存穿透缓存雪崩缓存击穿。这些问题在使用Redis作为缓存时经常遇到,但通过合理的策略可以有效解决。我会用简单易懂的方式来讲解,帮助你理解这些问题的原理和解决方案。


1. 缓存穿透

1.1 什么是缓存穿透?

缓存穿透是指查询一个数据库中不存在的数据,由于缓存不会保存这样的数据,每次查询都会直接穿透到数据库,从而增加数据库的压力。

1.2 为什么会出现缓存穿透?

  • 请求非法数据:用户请求了一个不存在的数据。

  • 缓存未命中:缓存中没有保存这样的数据,每次查询都会直接访问数据库。

1.3 如何解决缓存穿透?

  1. 接口层面校验

    • 在接口层面验证请求的合法性,避免非法请求直接穿透到数据库。

    • 例如,检查请求的ID是否合法,是否符合业务逻辑。

  2. 缓存空对象

    • 对于查询不存在的数据,将空对象或默认值缓存一段时间,避免每次查询都穿透到数据库。

    • 例如,缓存一个空的JSON对象或null值。

  3. 布隆过滤器

    • 使用布隆过滤器(Bloom Filter)预先存储可能存在的数据ID,查询时先检查布隆过滤器。

    • 如果布隆过滤器判断数据不存在,则直接返回,避免查询数据库。

示例代码

const cache = require('some-cache-library'); // 假设的缓存库
const database = require('some-database-library'); // 假设的数据库库async function getData(id) {// 检查缓存let data = cache.get(id);if (data) {return data;}// 查询数据库data = await database.query(id);if (data) {// 缓存数据cache.set(id, data, 3600); // 缓存1小时} else {// 缓存空对象cache.set(id, null, 60); // 缓存1分钟}return data;
}

2. 缓存雪崩

2.1 什么是缓存雪崩?

缓存雪崩是指在缓存层(如Redis)中的所有缓存数据同时过期,导致大量请求直接穿透到数据库,从而引发数据库压力剧增甚至崩溃。

2.2 为什么会出现缓存雪崩?

  • 缓存过期时间一致:所有缓存数据的过期时间相同,导致同时过期。

  • 缓存层宕机:缓存层(如Redis)宕机,所有请求直接穿透到数据库。

2.3 如何解决缓存雪崩?

  1. 设置不同的过期时间

    • 为缓存数据设置不同的过期时间,避免同时过期。

    • 例如,使用随机的过期时间范围。

  2. 使用本地缓存

    • 在应用层使用本地缓存(如Guava Cache),作为第一级缓存,减轻Redis的压力。

  3. 使用Redis集群

    • 使用Redis集群,避免单点故障。

  4. 预热缓存

    • 在系统启动时,预先加载热点数据到缓存中。

  5. 限流和降级

    • 在接口层面使用限流和降级策略,避免过多请求同时访问数据库。

示例代码

const cache = require('some-cache-library'); // 假设的缓存库
const database = require('some-database-library'); // 假设的数据库库async function getData(id) {// 检查缓存let data = cache.get(id);if (data) {return data;}// 查询数据库data = await database.query(id);if (data) {// 缓存数据,设置随机过期时间const randomExpire = 3600 + Math.floor(Math.random() * 3600); // 1-2小时cache.set(id, data, randomExpire);}return data;
}

3. 缓存击穿

3.1 什么是缓存击穿?

缓存击穿是指一个热点数据在缓存过期时,大量请求同时访问数据库,导致数据库压力剧增。

3.2 为什么会出现缓存击穿?

  • 热点数据过期:热点数据的缓存过期,导致大量请求同时访问数据库。

  • 高并发请求:在缓存过期时,大量并发请求同时到达。

3.3 如何解决缓存击穿?

  1. 使用互斥锁

    • 在缓存过期时,使用互斥锁(如Redis的SETNX命令)确保只有一个请求去查询数据库,其他请求等待。

    • 例如,使用SETNX命令设置一个锁,只有第一个请求能够查询数据库并更新缓存。

  2. 双层缓存

    • 使用两层缓存,第一层缓存(如本地缓存)过期时间稍短,第二层缓存(如Redis)过期时间稍长。

    • 第一层缓存过期时,第二层缓存仍然可用,避免直接穿透到数据库。

  3. 预热缓存

    • 在系统启动时,预先加载热点数据到缓存中,避免缓存过期时的高并发请求。

示例代码

const cache = require('some-cache-library'); // 假设的缓存库
const database = require('some-database-library'); // 假设的数据库库async function getData(id) {// 检查缓存let data = cache.get(id);if (data) {return data;}// 设置互斥锁const lockKey = `lock:${id}`;if (cache.set(lockKey, 'locked', 10)) { // 设置锁,过期时间10秒try {// 查询数据库data = await database.query(id);if (data) {// 更新缓存cache.set(id, data, 3600);}} finally {// 释放锁cache.del(lockKey);}} else {// 等待其他请求更新缓存await new Promise(resolve => setTimeout(resolve, 1000));data = cache.get(id);}return data;
}

4. 总结

  • 缓存穿透:查询不存在的数据,导致每次查询都穿透到数据库。

    • 解决方案:接口层面校验、缓存空对象、使用布隆过滤器。

  • 缓存雪崩:所有缓存数据同时过期,导致大量请求穿透到数据库。

    • 解决方案:设置不同的过期时间、使用本地缓存、使用Redis集群、预热缓存、限流和降级。

  • 缓存击穿:热点数据过期时,大量请求同时访问数据库。

    • 解决方案:使用互斥锁、双层缓存、预热缓存。

通过合理的策略和配置,可以有效解决Redis缓存中的这些问题,提高系统的稳定性和性能。

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

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

相关文章

附录-Python — 包下载缓慢,配置下载镜像

1️⃣命令行配置 pip config set global.index-url http://mirrors.aliyun.com/pypi/simple/ pip config set install.trusted-host mirrors.aliyun.com 2️⃣配置文件配置 1、打开文件夹,输入 %APPDATA% 回车 2、打开 %APPDATA% 路径,并在此路径下新建…

VS 2019 免费版 下载与安装 教程说明

推荐大家直接转到第13步,点击链接即可下载VS2019版本 1.VS官网 2.登录账号 3.在搜索栏输入“2019” 4.点击2019这个标题 5.点击“下载” 6.选择合适的版本下载 7.打开下载文件(若下载过程总是转圈圈,则换个网络下载即可) 8.安…

介绍 torch-mlir 从 pytorch 生态到 mlir 生态

一、引言 The Torch-MLIR project provides core infrastructure for bridging the PyTorch ecosystem and the MLIR ecosystem. For example, Torch-MLIR enables PyTorch models to be lowered to a few different MLIR dialects. Torch-MLIR does not attempt to provide a…

Java并发编程之ConcurrentHashMap的原理和使用

ConcurrentHashMap(CHM)是Java为解决高并发场景下哈希表性能瓶颈而设计的线程安全容器,其核心目标在于: 线程安全‌:避免多线程操作导致的数据不一致问题‌;高吞吐量‌:通过细粒度锁和无锁化设计降低线程竞争‌;动态扩展‌:支持自动扩容与数据结构优化(如链表转红黑树…

AbMole揭秘伤口愈合:IGF-1-SP1-CD248信号通路的新发现

科学家们揭示了一条新的信号通路——IGF-1-SP1-CD248,这一发现为理解伤口愈合障碍提供了新的视角,并为未来的研究开辟了新方向。 研究背景 糖尿病患者的伤口愈合是一个长期存在的挑战。据统计,约15%的糖尿病患者会遭受慢性伤口的困扰&#…

Go入门之文件

以只读方式打开文件 package mainimport ("fmt""io""os" )func main() {file, err : os.Open("./main.go")defer file.Close()if err ! nil {fmt.Println(err)return}fmt.Println(file)var tempSlice make([]byte, 128)var strSlice…

python量化交易——金融数据管理最佳实践——使用qteasy管理本地数据源

文章目录 统一定义的金融历史数据表最重要的数据表数据表的定义交易日历表的定义:交易日历表: trade_calendar qteasy是一个功能全面且易用的量化交易策略框架, Github地址在这里。使用它,能轻松地获取历史数据,创建交易策略并完…

通过 PromptTemplate 生成干净的 SQL 查询语句并执行SQL查询语句

问题描述 在使用 LangChain 和 Llama 模型生成 SQL 查询时,遇到了 sqlite3.OperationalError 错误。错误信息如下: OperationalError: (sqlite3.OperationalError) near "sql SELECT Name FROM MediaType LIMIT 5; ": syntax error [SQL: …

STaR(Self-Taught Reasoner)方法:让语言模型自学推理能力(代码实现)

STaR(Self-Taught Reasoner)方法:让语言模型自学推理能力 在大型语言模型(LLM)的推理能力优化中,STaR(Self-Taught Reasoner) 是一种引人注目的技术,属于“修改提议分布…

Asp.Net Web API| React.js| EF框架 | SQLite|

asp.net web api EF SQLiteReact前端框架 设计一个首页面,包含三个按钮分别对应三类用户(数据查看,设计人员,管理员),当点击管理员的时候弹出一个前端页面可以输入信息(以学生数据为例&#…

[SWPUCTF 2022 新生赛]1z_unserialize

题目描述&#xff1a;是很简单的反序列化噢 代码审计看注释 <?phpclass lyh{ //定义一个类为lyhpublic $url NSSCTF.com;//公共属性&#xff0c;初始值为NSSCTF.compublic $lt; //公共属性&#xff0c;没有初始值public $lly; //公共属性&…

【数据库】Update两阶段提交

为什么要两阶段提交 事务提交之后&#xff0c;redo log和bin log 都是需要1持久化到磁盘中&#xff0c;但是这两个是独立的逻辑&#xff0c;可能出现半成功的状态&#xff0c;这样就造成两份日志之间的逻辑不一致。如&#xff1a; 以id1&#xff0c;name ‘小明’执行 updat…

【蓝桥】排序

1、sort简介 sort函数包含在头文件<algorithm>中sort函数使用之前&#xff0c;需要通过#include <algorithm>引入sort函数使用的是快速排列或类似快速排列的改进算法&#xff0c;时间复杂度一般为O(nlog(n)) 2、sort用法 2.1 基础用法 #include <iostream>…

2024年中国城市统计年鉴(PDF+excel)

2024年中国城市统计年鉴&#xff08;PDFexcel&#xff09; 说明&#xff1a;包括地级县级市 格式&#xff1a;PDFEXCEL 《中国城市统计年鉴》是一部全面反映中国城市发展状况的官方统计出版物&#xff0c;包括各级城市的详细统计数据。这部年鉴自1985年开始出版&#xff0c;…

android 资源selector写法注意

1、res文件夹下面color文件夹,放的xml <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@color/color_brand1" android:s…

蓝桥杯 灯笼大乱斗【算法赛】

问题描述 元宵佳节&#xff0c;一场别开生面的灯笼大赛热闹非凡。NN 位技艺精湛的灯笼师依次落座&#xff0c;每位师傅都有相应的资历值&#xff0c;其中第 ii 位师傅的资历值为 AiAi​。从左到右&#xff0c;师傅们的资历值逐级递增&#xff08;即 A1<A2<⋯<ANA1​&l…

商城源码的框架

商城源码的框架通常是基于某种Web开发框架或者电子商务平台来构建的。以下是一些常见的商城源码框架&#xff1a; WooCommerce&#xff1a;基于WordPress的电子商务插件&#xff0c;适用于小型到中型的在线商店。 Magento&#xff1a;一个功能强大和灵活的开源电子商务平台&am…

HarmonyOS 5.0应用开发——多线程Worker和@Sendable的使用方法

【高心星出品】 文章目录 多线程Worker和Sendable的使用方法开发步骤运行结果 多线程Worker和Sendable的使用方法 Worker在HarmonyOS中提供了一种多线程的实现方式&#xff0c;它允许开发者在后台线程中执行长耗时任务&#xff0c;从而避免阻塞主线程并提高应用的响应性。 S…

避坑!用Docker搞定PHP开发环境搭建(Mac、Docker、Nginx、PHP-FPM、XDebug、PHPStorm、VSCode)

本次更新主要是对环境版本进行了更新&#xff0c;例如php 7.3.7升级到了7.3.8&#xff0c;另外之前的版本有同学踩了坑&#xff0c;主要是官方docker镜像php:7.3.7-fpm和php:7.3.8-fpm使用了不同版本的debian&#xff0c;后面会提到&#xff0c;请各位同学留意。 因为最近换电脑…

自动化测试开发

4、Servlet模型&#xff08;一&#xff09; Servlet的编写、访问过程 Servlet简介 Servlet是Java Servlet的简称&#xff0c;是小服务程序或服务连接器&#xff0c;是用Java编写的服务器端程序&#xff0c;主要功能在于获取请求&#xff0c;返回响应广义&#xff1a;一个Ser…