Redis之缓存穿透问题解决方案实践SpringBoot3+Docker
文章目录
- 一、介绍
- 二、方案介绍
- 三、Redis Docker部署
- 四、SpringBoot3 Base代码
- 1. 依赖配置
- 2. 基本代码
- 五、缓存优化代码
- 1. 校验机制
- 2. 布隆过滤器
- 3. 逻辑优化
一、介绍
当一种请求,总是能越过缓存,调用数据库,就是缓存穿透。
比如当请求一个数据库没有的数据,那么缓存也不会有,然后就一直请求,甚至高并发去请求,对数据库压力会增大。
二、方案介绍
- 如果
key
具有某种规则,那么可以对key增加校验机制,不符合直接返回。 Redisson
布隆过滤器- 逻辑修改,当数据库没有此数据,以
null
为value
,也插入redis
缓存,但设置较短的过期时间。
三、Redis Docker部署
docker-compose示例如下,redis.conf从这里下载
redis:container_name: redisimage: redis:7.2volumes:- ./redis/redis.conf:/usr/local/etc/redis/redis.confports:- "6379:6379"command: [ "redis-server", "/usr/local/etc/redis/redis.conf" ]
四、SpringBoot3 Base代码
1. 依赖配置
<!-- redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- redis 连接线程池 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.11.1</version></dependency><!-- redisson --><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.24.3</version></dependency>
spring: data:redis:host: 192.168.101.65 # Redis服务器的主机名或IP地址port: 6379 # Redis服务器的端口号password: # 用于连接Redis服务器的密码database: 0 # 要连接的Redis数据库的索引号lettuce:pool:max-active: 20 # 连接池中最大的活跃连接数max-idle: 10 # 连接池中最大的空闲连接数min-idle: 0 # 连接池中最小的空闲连接数timeout: 10000 # 连接超时时间(毫秒)lock-watchdog-timeout: 100 # Redisson的分布式锁的看门狗超时时间(毫秒)
2. 基本代码
要演示的代码很简单,就是一个携带courseId
请求过来,调用下面的service
函数,然后查询数据库。
@Overridepublic CoursePublish getCoursePublish(Long courseId) {return coursePublishMapper.selectById(courseId);}
当我们使用redis改造时,基本代码如下
@Overridepublic CoursePublish getCoursePublishCache(Long courseId) {String key = "content:course:publish:" + courseId;//先查询redisObject object = redisTemplate.opsForValue().get(key);if (object != null){String string = object.toString();CoursePublish coursePublish = JSON.parseObject(string, CoursePublish.class);return coursePublish;}else {//后查询数据库CoursePublish coursePublish = getCoursePublish(courseId);if (coursePublish != null){redisTemplate.opsForValue().set(key, JSON.toJSONString(coursePublish));}return coursePublish;}}
五、缓存优化代码
1. 校验机制
我这里的id
没规则,所以加不了,跳过。
2. 布隆过滤器
读取yaml
配置
@Data
@Component
@ConfigurationProperties(prefix = "spring.data.redis")
public class RedisProperties {private String host;private int port;private String password;private int database;private int lockWatchdogTimeout;
}
配置RedissonClient
@Slf4j
@Configuration
public class RedissionConfig {@Autowiredprivate RedisProperties redisProperties;@Beanpublic RedissonClient redissonClient() {RedissonClient redissonClient;Config config = new Config();//starter依赖进来的redisson要以redis://开头,其他不用String url = "redis://"+ redisProperties.getHost() + ":" + redisProperties.getPort();config.useSingleServer().setAddress(url)//.setPassword(redisProperties.getPassword()).setDatabase(redisProperties.getDatabase());try {redissonClient = Redisson.create(config);return redissonClient;} catch (Exception e) {log.error("RedissonClient init redis url:[{}], Exception:", url, e);return null;}}
}
把布隆过滤器加到service
,如下
private RBloomFilter<String> bloomFilter;@PostConstructpublic void init(){//初始化布隆过滤器bloomFilter = redissonClient.getBloomFilter("bloom-filter");bloomFilter.tryInit(100, 0.003);List<CoursePublish> coursePublishList = coursePublishMapper.selectList(new LambdaQueryWrapper<CoursePublish>());coursePublishList.forEach(coursePublish -> {String key = "content:course:publish:" + coursePublish.getId();bloomFilter.add(key);});}@Overridepublic CoursePublish getCoursePublishCache(Long courseId) {String key = "content:course:publish:" + courseId;//布隆过滤器boolean contains = bloomFilter.contains(key);if (!contains){return null;}//先查询redisObject object = redisTemplate.opsForValue().get(key);if (object != null){String string = object.toString();CoursePublish coursePublish = JSON.parseObject(string, CoursePublish.class);return coursePublish;}else {//后查询数据库CoursePublish coursePublish = getCoursePublish(courseId);if (coursePublish != null){bloomFilter.add(key);redisTemplate.opsForValue().set(key, JSON.toJSONString(coursePublish));}return coursePublish;}}
3. 逻辑优化
当数据库没有此数据,以null
为value
,也插入redis
缓存,但设置较短的过期时间。
//后查询数据库CoursePublish coursePublish = getCoursePublish(courseId);if (coursePublish != null) {bloomFilter.add(key);redisTemplate.opsForValue().set(key, JSON.toJSONString(coursePublish));}else {redisTemplate.opsForValue().set(key, JSON.toJSONString(coursePublish), 10, TimeUnit.SECONDS);}return coursePublish;
相关文章:

Redis之缓存穿透问题解决方案实践SpringBoot3+Docker
文章目录 一、介绍二、方案介绍三、Redis Docker部署四、SpringBoot3 Base代码1. 依赖配置2. 基本代码 五、缓存优化代码1. 校验机制2. 布隆过滤器3. 逻辑优化 一、介绍 当一种请求,总是能越过缓存,调用数据库,就是缓存穿透。 比如当请求一…...

每日shell脚本之超级整合程序3.0
每日shell脚本之超级整合程序3.0 本期带来之前的升级版2.0整合脚本程序,学习工作小利器,同时模块化构建方便二次开发。 上图 上源码 #!/usr/bin/bash # *******************************************# # * CDDN : M乔木 # # * qq邮箱 …...
Docker介绍与使用
Docker介绍与使用 目录: 一、Docker介绍 1、Docker概述与安装 2、Docker三要素 二、Docker常用命令的使用 1、镜像相关命令 2、容器相关命令 三、Docker实战之下载mysql、redis、zimg 一、Docker介绍 Docker是一个开源的应用容器引擎,让开发者可以打包…...
Gin框架: 使用go-ini配置参数与不同环境下的配置部署
关于 INI 配置文件与go-ini 1 )概述 在INI配置文件中可以处理各种数据的配置INI文件是一种简单的文本格式,常用于配置软件的各种参数go-ini 是地表 最强大、最方便 和 最流行 的 Go 语言 INI 文件操作库 Github 地址:https://github.com/go-…...

探究网络工具nc(netcat)的使用方法及安装步骤
目录 🐶1. 什么是nc(netcat)? 🐶2. nc(netcat)的基本使用方法 2.1 🥙使用 nc 进行端口监听 2.2 🥙使用 nc 进行端口扫描 2.3 🥙使用 Netcat 进行文件传输…...

深入浅出JVM(四)之类文件结构
深入浅出JVM(四)之类文件结构 Java文件编译成字节码文件后,通过类加载机制到Java虚拟机中,Java虚拟机能够执行所有符合要求的字节码,因此无论什么语言,只要能够编译成符合要求的字节码文件就能够被Java虚拟…...
Anaconda下的pkgs占用空间13G,如何安全的清理(已解决)
方法一:让Anaconda自行决定清理 执行命令 conda clean -p 我的Anaconda安装在D盘,具体位置如下。你的应该也能找到对应的位置 D:\*****\**\Anaconda3\pkgs (base) C:\Users\Liu_J>conda clean -p WARNING: C:\Users\***\.conda\pkgs does not ex…...

压缩感知常用的重建算法
重建算法的基本概念 在压缩感知(Compressed Sensing, CS)框架中,重建算法是指将从原始信号中以低于奈奎斯特率采集得到的压缩测量值恢复成完整信号的数学和计算过程。由于信号在采集过程中被压缩,因此重建算法的目标是找到最符合…...

c语言经典测试题2
1.题1 我们来思考一下它的结果是什么? 我们来分析一下:\\是转义为字符\,\123表示的是一个八进制,算一个字符,\t算一个字符,加上\0,应该有13个,但是strlen只计算\0前的字符个数。所以…...

⭐北邮复试刷题105. 从前序与中序遍历序列构造二叉树__递归分治 (力扣每日一题)
105. 从前序与中序遍历序列构造二叉树 给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder [9,3,15,…...

机房预约系统(个人学习笔记黑马学习)
1、机房预约系统需求 1.1系统简介 学校现有几个规格不同的机房,由于使用时经常出现“撞车“现象,现开发一套机房预约系统,解决这一问题。 1.2身份简介 分别有三种身份使用该程序 学生代表:申请使用机房教师:审核学生的预约申请管理员:给学生、教师创建账…...
7、内网安全-横向移动PTH哈希PTT票据PTK密匙Kerberos密码喷射
用途:个人学习笔记,有所借鉴,欢迎指正 目录 一、域横向移动-PTH-Mimikatz&NTLM 1、Mimikatz 2、impacket-at&ps&wmi&smb 二、域横向移动-PTK-Mimikatz&AES256 三、域横向移动-PTT-漏洞&Kekeo&Ticket 1、漏…...

【前端】夯实基础 css/html/js 50个练手项目(持续更新)
文章目录 前言Day 1 expanding-cardsDay 2 progress-steps 前言 发现一个没有用前端框架的练手项目,很适合我这种纯后端开发夯实基础,内含50个mini project,学习一下,做做笔记。 项目地址:https://github.com/bradtr…...

ELK入门(四)-logstash
Logstash Logstash 是开源的服务器端数据处理管道,能够同时从多个来源采集数据,转换数据,然后将数据发送到您最喜欢的存储库中。 Logstash 能够动态地采集、转换和传输数据,不受格式或复杂度的影响。利用 Grok 从非结构化数据中…...
laravel-admin的3个开发细节调整
在使用laravel-admin开发的过程中,根据官方开发文档Laravel admin | laravel-admin基本都能实现想要的效果,这里补充3个文档上没有描述的细节 Laravel8命令行创建控制器调整 在laravel-admin中可以使用php artisan admin:make UserController --modelAp…...

Redis--原理篇-数据结构(底层)
Redis数据结构 动态字符串SDS IntSet 统一大小并且内存地址连续 为了方便寻址 Dict 基本结构 扩容 收缩 Ziplist(P150 后半部分再看) Quicklist skiplist(满足中间查询 RedisObject...

OpenAI发布Sora模型,可根据文字生成逼真AI视频
早在2022年11月30日,OpenAI第一次发布人工智能聊天机器人ChatGPT,随后在全世界掀起了人工智能狂潮,颠覆了一个又一个行业。在过去的一年多的时间里,chatGPT的强大功能改变了越来越多人的工作和生活方式,成为了世界上用…...

视频生成模型:构建虚拟世界的模拟器 [译]
原文:Video generation models as world simulators 我们致力于在视频数据上开展生成模型的大规模训练。具体来说,我们针对不同时长、分辨率和宽高比的视频及图像,联合训练了基于文本条件的扩散模型。我们采用了一种 Transformer 架构&#…...

MySQL数据库基础(十二):子查询(三步走)
文章目录 子查询(三步走) 一、子查询(嵌套查询)的介绍 二、子查询的使用 三、总结 子查询(三步走) 一、子查询(嵌套查询)的介绍 在一个 select 语句中,嵌入了另外一个 select …...

2-21算法习题总结
由于蓝桥杯的题,我不知道从怎么复制,就只能粘贴图片了 翻硬币 代码 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);String start sc.next();char[] starts start.toCharArray();String end sc…...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...

Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...