Redis场景问题1:缓存穿透

Redis 缓存穿透是指在缓存系统(如 Redis)中,当客户端请求的数据既不在缓存中也不在数据库中时,每次请求都会直接穿透缓存访问数据库,从而给数据库带来巨大压力,甚至可能导致数据库崩溃。下面为你详细介绍其产生原因、解决方案以及示例代码。

产生原因

  • 非法请求:恶意攻击者可能会故意发送大量不存在于数据库中的请求,使缓存失去作用,请求全部落到数据库上。
  • 业务逻辑错误:在业务开发过程中,如果对数据的判断逻辑有误,可能会导致程序请求不存在的数据。

解决方案

1. 缓存空对象

当请求的数据在数据库中不存在时,将一个空对象(如null"")存入缓存,并设置一个较短的过期时间。这样下次相同的请求就会直接从缓存中获取空对象,而不会再次访问数据库。

2. 布隆过滤器

布隆过滤器是一种空间效率极高的概率型数据结构,用于判断一个元素是否存在于一个集合中。在请求访问缓存之前,先通过布隆过滤器判断该请求的数据是否可能存在。如果布隆过滤器判断数据不存在,那么就直接返回,避免访问数据库。

示例代码(Python + Redis)

以下是使用 Python 和 Redis 实现缓存空对象的示例代码:

import redis# 连接Redis
r = redis.Redis(host='localhost', port=6379, db=0)def get_data(key):# 先从缓存中获取数据data = r.get(key)if data is not None:# 如果缓存中有数据,直接返回if data == b'':return Nonereturn data.decode('utf-8')else:# 缓存中没有数据,从数据库中获取(这里用模拟函数代替)data = get_data_from_db(key)if data is None:# 如果数据库中也没有数据,缓存空对象r.setex(key, 60, '')  # 设置过期时间为60秒else:# 数据库中有数据,存入缓存r.setex(key, 3600, data)  # 设置过期时间为3600秒return datadef get_data_from_db(key):# 模拟从数据库中获取数据# 这里可以替换为实际的数据库查询操作if key == 'existing_key':return 'some data'return None# 测试
print(get_data('existing_key'))
print(get_data('non_existing_key'))

上述代码实现了一个简单的缓存空对象的机制,当请求的数据在数据库中不存在时,会将空对象存入缓存,避免下次请求再次访问数据库。

布隆过滤器示例(Python + RedisBloom)

如果你使用的是 RedisBloom 模块,可以使用布隆过滤器来解决缓存穿透问题:

from redisbloom.client import Client# 连接RedisBloom
rb = Client()# 初始化布隆过滤器
rb.bfCreate('mybloom', 0.01, 1000)  # 错误率为0.01,预计插入1000个元素# 向布隆过滤器中添加元素
rb.bfAdd('mybloom', 'existing_key')def get_data_with_bloom(key):# 先通过布隆过滤器判断元素是否可能存在if not rb.bfExists('mybloom', key):return None# 再从缓存中获取数据data = r.get(key)if data is not None:if data == b'':return Nonereturn data.decode('utf-8')else:data = get_data_from_db(key)if data is None:r.setex(key, 60, '')else:r.setex(key, 3600, data)return data# 测试
print(get_data_with_bloom('existing_key'))
print(get_data_with_bloom('non_existing_key'))

上述代码使用了 RedisBloom 模块的布隆过滤器,在请求访问缓存之前,先通过布隆过滤器判断元素是否可能存在,从而减少不必要的数据库访问。

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

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

相关文章

CUDA Memory Fence 函数的功能与硬件实现细节

CUDA Memory Fence 函数的功能与硬件实现细节 Memory Fence 的基本功能 CUDA中的memory fence函数用于控制内存操作的可见性顺序,确保在fence之前的内存操作对特定范围内的线程可见。主要功能包括: 排序内存操作:确保fence之前的内存操作在…

实战篇Redis

黑马程序员的Redis的笔记(后面补一下图片) 【黑马程序员Redis入门到实战教程,深度透析redis底层原理redis分布式锁企业解决方案黑马点评实战项目】https://www.bilibili.com/video/BV1cr4y1671t?p72&vd_source001f1c33a895eb5ed820b9a4…

Reactive编程:什么是Reactive编程?Reactive编程思想

文章目录 **1. Reactive编程概述****1.1 什么是Reactive编程?****1.1.1 Reactive编程的定义****1.1.2 Reactive编程的历史****1.1.3 Reactive编程的应用场景****1.1.4 Reactive编程的优势** **1.2 Reactive编程的核心思想****1.2.1 响应式(Reactive&…

异步转同步,实现一个消息队列

有一个场景,需要实现一个消息队列,要求 1,3,4 秒后,依次打印 1,2,3,如下: 其实考察的是怎么用同步的方式实现异步。 本文总结了四种方式实现:常规嵌套、prom…

【Spring Boot 与 Spring Cloud 深度 Mape 之十】体系整合、部署运维与进阶展望

【Spring Boot 与 Spring Cloud 深度 Mape 之十】体系整合、部署运维与进阶展望 #微服务实战 #Docker #Kubernetes #SpringSecurity #OAuth2 #分布式事务 #Seata #ServiceMesh #总结 #SpringCloud #SpringBoot 系列终章:经过前九篇 [【深度 Mape 系列】] 的系统学习…

求职笔试题

PDD 最长公共子序列 1143-最长公共子序列 class Solution:def longestCommonSubsequence(self, text1: str, text2: str) -> int:"""二维动态规划"""m, n len(text1), len(text2)# dp [[0]* (n1)] * (m1) 这种写法错误,m1行…

【MySQL基础-16】MySQL DELETE语句:深入理解与应用实践

1. DELETE语句基础:数据删除的艺术 在数据库管理中,DELETE语句是维护数据完整性和清理过期信息的关键工具。与日常生活中的"删除"不同,数据库中的删除操作需要更加谨慎和精确,因为数据一旦删除,恢复可能非常…

python学习笔记(3)——元组

Python3 元组全面详解 一、元组的定义与特性 基本概念 元组(Tuple)是Python中的不可变序列,用小括号()表示,元素用逗号分隔。与列表不同,元组一旦创建,元素不能修改、添加或删除(元素本身为可变对象的情况除外)。 不可变性 • 元组的每个元素的引用不可变,但若元素是可…

Android 中实现一个自定义的 AES 算法

版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/ 前言 AES(Advanced Encryption Standard,高级加密标准) 是一种 对称加密算法,用于加密和解密数据。AES 由 美国…

小河:团队金牌精准计划

【趋势识别与预测】 数据趋势分析在随机序列研究中首要价值在于识别潜在规律并提升预测能力。随机序列常表现为无规则波动,但通过滑动平均、指数平滑、小波变换等方法,可剥离噪声干扰,提取长期趋势或周期性成分。例如,在金融时间序…

S32K144外设实验(七):FTM输出多路互补带死区PWM

文章目录 1. 概述1.1 时钟系统1.2 实验目的2. 代码的配置2.1 时钟配置2.2 FTM模块配置2.3 输出引脚配置2.4 API函数调用1. 概述 互补对的PWM输出是很重要的外设功能,尤其应用再无刷电机的控制。 1.1 时钟系统 笔者再墨迹一遍时钟的设置,因为很重要。 FTM的CPU接口时钟为SY…

数据结构与算法:算法分析

遇到的问题,都有解决方案,希望我的博客能为您提供一点帮助。 本篇参考《Data Structures and Algorithm Analysis in C》 “在程序设计中,不仅要写出能工作的程序,更要关注程序在大数据集上的运行时间。” 本章讨论要点&#xf…

Redis数据持久化机制 + Go语言读写Redis各种类型值

Redis(Remote Dictionary Server)作为高性能的键值存储系统,凭借其丰富的数据类型和原子性操作,成为现代分布式系统中不可或缺的组件。 1、Redis支持的数据类型 Redis支持的数据类型可归纳为以下9类: String&#x…

排序--归并排序

一,引言 归并排序作为七大排序中一种,本文将讲解其排序原理和代码实现。 二,逻辑讲解 来看一组动图: 首先先进行大逻辑的讲解,在一个乱序的数组中如图: 通过递归进行一次次分组如图: 分组逻…

React程序打包与部署

===================== 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 为生产环境准备React应用最小化和打包环境变量错误处理部署到托管服务部署到Netlify探索高级主题:Hooks、Su…

Spring Data审计利器:@LastModifiedDate详解(依赖关系补充篇)!!!

🕒 Spring Data审计利器:LastModifiedDate详解🔥(依赖关系补充篇) 🔌 核心依赖解析 使用LastModifiedDate必须知道的依赖关系 #mermaid-svg-qm1OUa9Era9ktbeK {font-family:"trebuchet ms",verd…

接口测试中数据库验证,怎么解决?

在接口测试中,通常需要在接口调用前后查询数据库,以验证接口操作是否正确影响了数据库状态。​这可以通过数据库断言来实现,PyMySQL库常用于连接和操作MySQL数据库。​通过该库,可以在测试中执行SQL语句,查询或修改数据…

游戏引擎学习第189天

今天的回顾与计划 在昨天,我们花了一些时间来优化调试数据的收集方法,并且在调试界面中增加了一些界面代码,使得我们可以悬停在不同的元素上,查看相关信息。今天的任务是对这些数据进行更多的操作,进行一些有趣的实验…

智能粉尘监测解决方案|守护工业安全,杜绝爆炸隐患

在厂房轰鸣的生产线上,一粒微小粉尘的聚集可能成为一场灾难的导火索。如何实现粉尘浓度的精准监控与快速响应?我们为您打造了一套"感知-预警-处置"全闭环的智能安全方案! 行业痛点:粉尘管理的生死线 在金属加工、化工…

Java 实现将Word 转换成markdown

日常的开发中&#xff0c;需要将word 等各类文章信息转换成格式化语言&#xff0c;因此需要使用各类语言将word 转换成Markdown 1、引入 jar包 <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version&g…