redis穿透解决方案

Redis缓存穿透是指查询一个不存在于数据库中的数据(通常是恶意用户发起的连续请求),由于缓存中没有,每次请求都会穿透到数据库,这可能会对数据库造成不必要的压力。解决缓存穿透问题的常见策略包括:
       1.  布隆过滤器:用于判断一个元素是否可能存在于集合中,即使它返回存在,也可能是个假阳性(误报),但不会出现假阴性(即如果布隆过滤器说不存在,则该元素一定不存在)。因此,可以在查询数据库之前先检查布隆过滤器。

       2.  空值缓存:即使数据库中没有找到对应记录,也将空值(如null)写入缓存,并设置一个较短的有效期。这样,后续相同请求在缓存有效期内可以直接从缓存中得到结果,而不需要再次访问数据库。

       3. 设置黑白名单:通过白名单使需要的请求访问,通过黑名单防止攻击。

首先,确保你的项目中包含了Spring Data Redis和Guava的依赖。

布隆过滤器配置

import com.google.common.hash.Funnel;
import com.google.common.hash.Hashing;
import com.google.common.math.LongMath;
import com.google.common.primitives.Chars;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 布隆过滤器配置类,用于初始化布隆过滤器的实例及其相关组件。*/
@Configuration
public class BloomFilterConfig {/*** 创建字符串处理的Funnel,用于将字符串转换为哈希输入。* * @return 字符串Funnel实例*/@Beanpublic Funnel<String> stringFunnel() {return (from, into) -> Chars.forEachUtf8(from, c -> into.putChar(c));}/*** 初始化布隆过滤器,基于预期插入数量和误报率进行配置。* * @param funnel 字符串处理的Funnel* @return 布隆过滤器实例*/@Beanpublic BloomFilter<String> bloomFilter(Funnel<String> funnel) {int expectedInsertions = 100000; // 预计需要插入过滤器的元素数量double fpp = 0.01; // 可接受的误报率,即预测为存在但实际上不存在的概率// 计算所需的哈希函数数量int numHashFunctions = LongMath.log2(LongMath.pow(2, Long.SIZE) / expectedInsertions * fpp);// 创建布隆过滤器实例return BloomFilter.create(funnel, expectedInsertions, fpp, Hashing.murmur3_128());}
}

缓存服务实现

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;/*** 缓存服务实现类,负责处理数据的缓存逻辑,包括使用布隆过滤器和空值缓存策略防止缓存穿透。*/
@Service
public class CacheService {private final StringRedisTemplate redisTemplate;private final BloomFilter<String> bloomFilter;/*** 构造函数注入Redis模板和布隆过滤器实例。** @param redisTemplate Redis操作模板* @param bloomFilter 布隆过滤器实例*/@Autowiredpublic CacheService(StringRedisTemplate redisTemplate, BloomFilter<String> bloomFilter) {this.redisTemplate = redisTemplate;this.bloomFilter = bloomFilter;}/*** 获取数据的方法,首先检查布隆过滤器,然后尝试从Redis缓存中获取,* 若缓存未命中且布隆过滤器认为可能存在,则查询数据库,并实施空值缓存策略。** @param key 数据的唯一标识* @return 查询到的数据或空值、提示信息*/public String getData(String key) {// 使用布隆过滤器快速判断key是否可能存在,减少不必要的数据库查询if (!bloomFilter.mightContain(key)) {return "This key is likely not in the database.";}// 尝试从Redis缓存中获取数据String value = redisTemplate.opsForValue().get(key);// 如果缓存未命中,且布隆过滤器判断可能在数据库中,则查询数据库if (value == null) {value = databaseFetch(key);// 数据库中也不存在,则将空值写入缓存,设置较短过期时间以避免长时间占用缓存if (value == null) {redisTemplate.opsForValue().set(key, "", 5, TimeUnit.MINUTES);} else {// 数据库中存在,则正常缓存该值redisTemplate.opsForValue().set(key, value);}}return value;}/*** 模拟从数据库获取数据的方法,实际应用中应替换为真实的数据库访问逻辑。** @param key 数据查询键* @return 从数据库查询到的数据或null*/private String databaseFetch(String key) {// 示例中始终返回null,表示数据库中也没有该数据return null;}
}

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

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

相关文章

CarService的构成和初始化分析

以下分析&#xff0c;基于安卓13的AAOS。 代码构成 packages/services/Car CarService相关代码&#xff0c;主要是在这个目录下 frameworks/opt/car/services 主要是carservice启动相关。 其它目录&#xff1a;audio_policy_configuration.xml和car_audio_configuration.xm…

Unity Texture2D读取像素时出错问题

Texture2D在读取像素处理时&#xff0c;经常会出错&#xff0c;这个时候可以用如下函数先转换&#xff1a; public Texture2D DeCompress(Texture2D source){RenderTexture renderTex RenderTexture.GetTemporary(source.width,source.height,0,RenderTextureFormat.Default,R…

leetcode-12-[226]翻转二叉树[101]对称二叉树[104]二叉树的最大深度[111]二叉树的最小深度

前置知识&#xff1a; 深度&#xff1a;任意节点到根节点的节点数 高度&#xff1a;任意节点到叶子节点&#xff08;左右孩子都为空&#xff09;的节点数 一、[226]翻转二叉树 重点&#xff1a;交换节点应该传入根节点 class Solution {public TreeNode invertTree(TreeNo…

JSON学习

一、JSON 1.1 简介 JSON&#xff1a;JavaScript Object Notation是一种表示对象的方式 基于JavaScript语言的轻量级的数据交换格式;&#xff08;即:用来传输数据的一种格式&#xff09; 现在传输数据的方式更多是采用json的格式&#xff0c;渐渐代替了XML 1.2 JSON的数据表示 …

人生的乐趣,在于对真知的追求

子曰&#xff1a;朝闻道&#xff0c;夕死可矣&#xff01; 孔子说&#xff1a;早上听到关于世界的真理&#xff0c;哪怕晚上就die了都可以。 这句话很有力量而经常被人引用&#xff0c;表达出我们如何看待沉重的肉身和精神世界。 我们的生活目的&#xff1a;道。 —— 要了解…

MongoDB查询

一、find 1、简单查询 #查寻所有文档 >db.foo.find()#查询包含namehgq的文档 >db.foo.find({"name":"hgq"}) #查询包含namehgq&#xff0c;age12的文档&#xff0c;默认为全部条件都匹配 >db.foo.find({"name":"hgq","…

探究 IP 地址被网站封禁的原因

在我们登录各种网站、APP浏览时&#xff0c;可能会遇到 IP 地址被某些网站封禁的情况。很多人奇怪这是为什么呢&#xff1f; 首先&#xff0c;违反网站的使用规则是比较常见的原因之一。比如&#xff0c;频繁发送垃圾邮件、恶意评论、进行网络攻击或试图破解网站的安全机制等不…

数据链路层知识分享【计算机网络】【以太网帧 | MTU的影响 | ARP技术】

博客主页&#xff1a;花果山~程序猿-CSDN博客 文章分栏&#xff1a;Linux_花果山~程序猿的博客-CSDN博客 关注我一起学习&#xff0c;一起进步&#xff0c;一起探索编程的无限可能吧&#xff01;让我们一起努力&#xff0c;一起成长&#xff01; 目录 前文 一&#xff0c; 以…

【操作系统】操作系统课后作业-聊天程序

无名管道与有名管道的区别 无名管道&#xff1a; 它是半双工的&#xff0c;具有固定的读端和写端。 只能用于具有亲缘关系的进程之间的通信&#xff08;也是父子进程或者兄弟进程之间&#xff09;。 不是普通的文件&#xff0c;不属于其他任何文件系统&#xff0c;并且只存…

Electron+Vue开源软件:洛雪音乐助手V2.8畅享海量免费歌曲

洛雪音乐助手是一款功能全面且完全免费的开源音乐软件&#xff0c;支持在Windows、Android和iOS平台上使用。 平台支持&#xff1a; 桌面版&#xff1a;采用Electron Vue技术栈开发&#xff0c;支持Windows 7及以上版本、Mac OS和Linux&#xff0c;具有广泛的用户群体覆盖。 …

深信服终端安全管理系统EDR版本升级过程

EDR当前版本为3.7.12&#xff0c;具体参考版本详情参数。需要升级到6.0.2R1版本&#xff0c;该版本更改了产品名称&#xff0c;叫做“统一端点安全管理系统aES” 当前版本详情 版本基础信息 软件版本&#xff1a;3.7.12.3829 病毒库版本&#xff1a;20240618174426 漏洞规则库&…

【安全边界】

1.安全边界是什么 安全边界是具有不同安全要求或需求的任意两个区域、子网或环境之间的交叉线。它存在于高安全性区域和低安全性区域之间&#xff0c;例如局域网&#xff08;LAN&#xff09;和互联网&#xff08;Internet&#xff09;之间。 2.为什么要建设安全边界 安全边界…

PHP入门教程5:会话管理和数据库操作

PHP入门教程5&#xff1a;会话管理和数据库操作 在前几篇文章中&#xff0c;我们学习了PHP的基础语法、控制结构、函数的使用、数组和字符串的操作&#xff0c;以及文件处理和表单处理。本文将重点介绍PHP中的会话管理和数据库操作&#xff0c;这是构建动态网站和Web应用程序的…

java.sql.Timestamp用法总结

java.sql.Timestamp用法总结 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 1. 概述 java.sql.Timestamp是Java中表示日期和时间的类&#xff0c;它继承自jav…

定制化物联网设备:开启智能生活新篇章

随着科技的进步&#xff0c;物联网&#xff08;IoT&#xff09;已成为我们日常生活和工作中不可或缺的一部分。从智能家居到工业自动化&#xff0c;物联网设备以其独特的功能和特性&#xff0c;极大地提高了我们的生活质量和工作效率。然而&#xff0c;在众多的物联网设备中&am…

Window常用的脚本有哪些?快来看看有哪些是你正在用的!(欢迎评论补充~)

前言 在日常开发中&#xff0c;如果能熟练掌握以下这些使用频率很高的脚本&#xff0c;那工作起来真的是手拿把攥&#xff0c;事半功倍&#xff0c;接下来给大家介绍一些我们日常使用率很高的一些脚本&#xff01; 常用脚本(Batchfile & VBScript) 1.一键启动.bat 一次…

负利率(Negative Interest Rates)是什么?商业银行会对普通储户实施负利率吗?

负利率是什么&#xff1f; 中文版 负利率是指中央银行或金融机构对存款人收取存款费用&#xff0c;而不是支付利息。这意味着存款人在银行存钱不仅不能赚取利息&#xff0c;反而要支付费用。以下是对负利率的详细解释&#xff1a; 负利率的理解 定义&#xff1a; 负利率意味…

ServletResponse类及其使用方法介绍

在Java Servlet技术中&#xff0c;ServletResponse是一个接口&#xff0c;它定义了服务器响应客户端请求的API。这个接口提供了设置响应头、发送错误、以及管理响应内容的方法。以下是对ServletResponse接口中一些重要方法的介绍以及它们的使用示例。 ServletResponse接口概述…

每年1-1.2万人毕业,男女比例约3:1,测绘工程的就业率如何

测绘工程&#xff0c;一个让人闻风丧胆的理科专业&#xff0c;虎扑评分4.2&#xff1a; 干过测绘的&#xff0c;苦不苦只有大家心里知道&#xff0c;带大家来感受一下&#xff0c;兄弟们的精神状态都十分美妙&#xff1a; 测绘专业到底是什么情况&#xff1f; PS.测绘分为本科…

mongodb-java apispringboot整合mongodb

mongodb入门mongodb-java api的使用springboot整合mongodb评论 一 MongoDB 1.1 MongoDB简介 ​ MongoDB是一个基于分布式文件存储的数据库。由C语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。 ​ MongoDB是一个介于关系数据库和非关系数据库之间的产品&…