【SpringBoot篇】解决缓存击穿问题① — 基于互斥锁方式
文章目录
- 🌹什么是缓存击穿
- 🌺基于互斥锁解决问题
- 🛸思路
- 🏳️🌈代码实现
🌹什么是缓存击穿
缓存击穿是指在使用缓存系统时,对一个热点数据的高并发请求导致缓存失效,多个请求同时访问数据库,造成数据库压力过大,性能下降。
具体来说,缓存击穿通常发生在以下情况下:
- 热点数据失效:当某个热点数据的缓存过期或被删除时,此时如果有大量的并发请求同时访问该数据,缓存系统无法命中缓存,每个请求都会直接访问数据库。
- 频繁更新数据:某个数据被频繁地修改,导致缓存频繁失效,而此时大量的请求同时访问该数据,造成缓存击穿。
缓存击穿会严重影响系统的性能和可用性,因为数据库无法处理如此高的并发请求,导致系统响应变慢甚至崩溃。
但是对于缓存击穿,我们有什么方法可以解决呢
🌺基于互斥锁解决问题
互斥锁(Mutex)是一种并发编程中用于保护共享资源的机制,它可以确保在同一时刻只有一个线程可以访问共享资源,从而避免多个线程同时对共享资源进行读写操作而导致的数据竞争和不确定性行为。
互斥锁的主要特点包括:
- 独占性:当一个线程获得了互斥锁后,其他线程就无法再获得该互斥锁,直到持有该锁的线程释放它。
- 阻塞和等待:如果一个线程尝试获取已被其他线程持有的互斥锁,那么它会被阻塞,直到该互斥锁被释放。
- 原子性:互斥锁的获取和释放操作是原子的,不会被打断。
互斥锁通常用于以下场景:
- 在多线程环境下保护共享资源,如共享变量、共享数据结构等,防止多个线程同时修改造成数据不一致。
- 控制对临界区的访问,确保同一时间只有一个线程能够执行临界区代码,以避免竞态条件(Race Condition)的发生。
🛸思路
使用互斥锁来解决缓存击穿问题的思路是通过对关键代码块进行加锁
,保证在同一时间只有一个线程能够执行这段代码。这样可以有效地避免多个线程同时访问数据库,减轻数据库的压力,提高系统的性能和可用性。
在解决缓存击穿问题时,通常会使用互斥锁锁住以下几个关键步骤:
- 检查缓存:首先检查缓存中是否存在所需数据。
- 缓存失效处理:如果缓存中不存在所需数据,即缓存失效,需要进行进一步处理。
- 加锁:在进行缓存失效处理之前,获取互斥锁,确保只有一个线程能够执行后续的数据库查询和缓存更新操作。
- 数据查询和缓存更新:在成功获得互斥锁之后,执行数据库查询操作,获取所需数据,并将数据更新到缓存中。
- 释放锁:缓存更新完成后,释放互斥锁,允许其他等待的线程获得锁并从缓存中获取数据。
通过加锁的方式,保证了同一时间只有一个线程能够执行关键代码块,避免了缓存击穿问题。其他线程在等待期间可以从缓存中获取旧数据,而不会直接访问数据库。这样可以减少数据库的并发访问压力,提升了系统的并发能力和性能。
需要注意的是,互斥锁的使用应该谨慎,避免持有锁的时间过长,否则可能会导致其他线程的延迟和性能下降。在设计时,要权衡锁的粒度和性能需求,确保互斥锁的使用场景合理,并根据具体情况选择合适的锁机制(如读写锁、分布式锁等)进行优化。
🏳️🌈代码实现
我们看下面的例子
@Service
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic Result queryById(Long id) {//缓存穿透
// Shop shop=queryWithPassThrough(id);//互斥锁解决缓存击穿Shop shop=queryWithMutex(id);if(shop==null){return Result.fail("店铺不存在");}//返回return Result.ok(shop);}public Shop queryWithMutex(Long id){String key=CACHE_SHOP_KEY+":"+id;//从redis中查询缓存String shopJson=stringRedisTemplate.opsForValue().get(key);//判断是否存在if(StrUtil.isNotBlank(shopJson)){//存在,直接返回return JSONUtil.toBean(shopJson, Shop.class);}//判断命中的是否是空值if(shopJson!=null){//返回一个错误信息return null;}//实现缓存重建//获取互斥锁String lockKey="lock:shop"+id;Shop shop=null;try {boolean isLock=tryLock(lockKey);//判断是否获取成功if (!isLock){//失败,那么休眠并且重试Thread.sleep(100);return queryWithMutex(id);}//成功,则根据id查询数据库shop=getById(id);//不存在,返回错误if(shop==null){//将空值写入到redisstringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL,TimeUnit.MINUTES);return null;}//存在,写入到redis里面stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL,TimeUnit.MINUTES);}catch (Exception e){throw new RuntimeException(e);}finally {//释放互斥锁unlock(lockKey);}//返回return shop;}//存在,写入到redis里面stringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shop),CACHE_SHOP_TTL,TimeUnit.MINUTES);//返回return shop;}//获取锁private boolean tryLock(String key){Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(key, "1", 10, TimeUnit.SECONDS);return BooleanUtil.isTrue(flag);}//释放锁private void unlock(String key){stringRedisTemplate.delete(key);}
}
在技术的道路上,我们不断探索、不断前行,不断面对挑战、不断突破自我。科技的发展改变着世界,而我们作为技术人员,也在这个过程中书写着自己的篇章。让我们携手并进,共同努力,开创美好的未来!愿我们在科技的征途上不断奋进,创造出更加美好、更加智能的明天!
相关文章:
【SpringBoot篇】解决缓存击穿问题① — 基于互斥锁方式
文章目录 🌹什么是缓存击穿🌺基于互斥锁解决问题🛸思路 🏳️🌈代码实现 🌹什么是缓存击穿 缓存击穿是指在使用缓存系统时,对一个热点数据的高并发请求导致缓存失效,多个请求同时访…...
系列一、GitHub搜索技巧
一、GitHub搜索技巧 1.1、概述 作为程序员,GitHub大家应该都再熟悉不过了,很多时候当我们需要使用某一项技能而又无从下手时,通常会在百度(面向百度编程)或者在GitHub上通过关键字寻找相关案例,比如我想学…...
35.java后端面试宝典
一、自我介绍。 我叫什么,这次是应聘什么岗位,会什么技术,会什么框架,熟练掌握框架之间的整合技术,做过什么项目并且介绍主要做了什么,并且可以为公司带来什么价值。 总的来说,初级Java工程师岗…...
Linux 磁盘空间占满故障解决方法
故障排查: 使用命令查看磁盘使用量 # 使用人类可读的格式(预设值是不加这个选项的...) df -h # --inodes 列出 inode 资讯,不列出已使用 block df -i # 查看当前目录下各个文件及目录占用空间大小 du -sh / 情况一:一般磁盘空间满了&a…...
让生活更智能,P1600边缘智能网关带你进入智能家居新时代
一、什么是P1600边缘智能网关? 在科技日新月异的今天,我们的生活已经被各种智能产品所包围。而在这个智能化的浪潮中,P1600边缘智能网关以其独特的优势,成为了智能家居的重要组成部分。那么,什么是P1600边缘智能网关呢…...
Java与前端:2023年的真实状况与焦虑解读
一、引言 在2023年,IT圈中流传着一些关于Java和前端的言论,这些言论引起了广泛的关注。有些人认为“Java已死、前端已凉”,而另一些人则持不同观点。那么,这些言论背后的真相是什么?它们是在贩卖焦虑吗?本…...
adb 基本命令合集
1.获取所有的包信息: adb shell pm list packages com.yu.weskul 2.清除APP缓存 adb shell pm clear <package-name> 3.查看当前应用及Activity adb shell dumpsys window | findstr "mCurrentFocus" 4.查看应用详细信息 adb shell dumpsys pack…...
[RK-Linux] RK3399支持M.2 NVMe SSD启动
延续《[RK-Linux] 从主线U-Boot移植PCIe及其PHY驱动到RK3399 U-Boot》 启动流程: maskrom -> loader(从 eMMC 存储器加载) -> u-boot(从 eMMC 存储器加载)-> kernel (从 M.2 NVMe SSD 加载)-> rootfs (从 M.2 NVMe SSD 挂载)配置从 M.2 NVMe SSD 启动: …...
LTO-3 磁带机种草终于是用上了
跑来跑去,买了不少配件,终于是把这磁带机给用上了,已经备份好了300 多 GB 的数据。 我们用了 NAS 的数据压缩功能,把需要备份的文件用 NAS 压缩成一个 Zip 文件,如果你可以 tar 的话也行。 这样传输速度更快…...
【全网首发】洛谷P1020 [NOIP1999 提高组] 导弹拦截
P1020 导弹拦截 の 题目传送门。 解题思路 显然,第一问求的是最长不上升子序列。 于是接下来直接抛开第一问不谈,也不考虑优化,直接考虑第二问。待会就知道原因了。 引理:Dilworth 定理 狄尔沃斯定理亦称偏序集分解定理&#…...
trino-435版本windows下源码编译
一、源码下载地址 https://github.com/trinodb/trino/tags 二、编译环境及工具准备 1、maven (1)版本:3.6.3 (2)settings.xml配置 <?xml version"1.0" encoding"UTF-8"?> <settin…...
java类和对象的思想概述
0.面向对象Object OOP——名人名言:类是写出来的,对象是new出来的 **> 学习面向对象的三条路线 java类以及类成员:(重点)类成员——属性、方法、构造器、(熟悉)代码块、内部类面向对象特征&…...
ant design vue3中引入message消息提示,全局引入亲测有效
两种方式 第一种:使用provide和inject方式 第二种:使用全局挂载$message方式 第一种: //main.ts import { createApp } from vue; import App from ./App; import Antd,{ message } from ant-design-vue; import ant-design-vue/es/mess…...
UE5 Landscape 制作GIS卫星图地形
1. 总体想法: 制作GIS地形,使用Landscaping MapBox是一个好方法,但是区域过大,会占用很多内存 https://blog.csdn.net/qq_17523181/article/details/135029614 如果采用QGis,导出卫星图,在UE5里拼合出地形…...
opencv入门到精通——改变颜色空间
目录 目标 改变颜色空间 对象追踪 如何找到要追踪的HSV值? 目标 在本教程中,你将学习如何将图像从一个色彩空间转换到另一个,像BGR↔灰色,BGR↔HSV等 除此之外,我们还将创建一个应用程序,以提取视频中的…...
法线贴图实现地形模型皱褶、凹凸不平的纹理效果
在线工具推荐: 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 法线贴图在3D建模中扮演着重要的角色,它通过模拟表面的微…...
【SpringBoot篇】基于Redis实现生成全局唯一ID的方法
文章目录 🍔生成全局唯一ID🌹为什么要生成全局唯一id🌺生成全局id的方法✨代码实现 🍔生成全局唯一ID 是一种在分布式系统下用来生成全局唯一id的工具 在项目中生成全局唯一ID有很多好处,其中包括: 数据…...
轻度听力损失的儿童需要早期干预吗?
一些宝宝在做听力筛查时总是不通过,进一步听力诊断发现宝宝有轻度的听力损失,刚知道这个消息时,家长可担心了,总想着宝宝是不是听不到啊?但是一段时间后,有些家长又会忽略宝宝的听力问题,因为部…...
【Spring Security】认证密码加密Token令牌CSRF的使用详解
🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《Spring Security》。🎯🎯 …...
python一点通: 一文讲清Post 和 Put操作区别!
当我们使用网络服务时,如果我们不能小心地区分 POST 和 PUT,有时可能会触发错误。 在 Web 开发世界中,特别是在处理 RESTful API 时,HTTP 方法 POST 和 PUT 经常被使用,但常常被误解。这两者都用于向服务器发送数据&a…...
通过 Higress Wasm 插件 3 倍性能实现 Spring-cloud-gateway 功能
作者:韦鑫,Higress Committer,来自南京航空航天大学分布式系统实验室 导读:本文将和大家一同回顾 Spring Cloud Gateway 是如何满足 HTTP 请求/响应转换需求场景的,并为大家介绍在这种场景下使用 Higress 云原生网关的…...
0.618算法和基于Armijo准则的线搜索回退法
0.618代码如下: import math # 定义函数h(t) t^3 - 2t 1 def h(t): return t**3 - 2*t 1 # 0.618算法 def golden_section_search(a, b, epsilon): ratio 0.618 while (b - a) > epsilon: x1 b - ratio * (b - a) x2 a ratio * (b - a) h_…...
DPDK单步跟踪(3)-项目配置和单步跟踪
项目配置 下面都是示例的情况,请大家根据自己的工程来修改 ## 首先是配置CMake build setting Debug setting 这里最重要的是: –proc-type secondary 表示这是以secondary模式启动的dpdk客户端。 ## path mapping 然后根据自己的需要,配置…...
.NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式
之前写过使用自定义返回类的方式来统一接口数据返回格式,.Net Core webapi RestFul 统一接口数据返回格式-CSDN博客 但是这存在一个问题,不是所有接口会按照定义的数据格式返回,除非每个接口都返回我们自定义的类,这种实现起来不…...
vue3 使用addRoute动态添加路由,页面刷新就白屏解决办法
问题,通过接口动态添加路由,第一次从登录页跳转还是正常的,说明路由添加成功了,但是刷新后就白屏了,且控制台报错路由匹配不到,在项目的main.js,router和路由拦截器中添加了一大堆打印后发现&am…...
探索鸿蒙:了解华为鸿蒙操作系统的基础课程
目录 学习目标: 学习内容: 学习时间: 学习产出: 介绍鸿蒙操作系统的起源和发展历程。 理解鸿蒙操作系统的核心概念和体系结构。 学习如何搭建和配置鸿蒙开发环境。 掌握基础的鸿蒙应用开发技术,包括应用的创建、…...
【Linux】进程周边007之进程控制
👀樊梓慕:个人主页 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》 🌝每一个不曾起舞的日子,都是对生命的辜负 目录 前言 1.进程创建 2.进程终止 2.…...
【C++】vector容器的模拟实现
目录 一,框架设计 二,构造函数 三,析构函数 四,赋值运算符 五,容器接口的实现 1,迭代器实现 2,“ [] ”运算符的实现 3,swap交换和resize重设大小 4,insert插入…...
华为Harmony——ArkTs语言
文章目录 一、简单示例二、声明式UI描述创建组件无参有参数 配置属性配置事件配置子组件 三、自定义组件基本用法基本结构成员函数/变量 一、简单示例 我们以一个具体的示例来说明ArkTS的基本组成。如下图所示,当开发者点击按钮时,文本内容从“Hello Wo…...
uniapp使用colorUI
colorUI 微动画 | ColorUI 使用文档 1:把colorui里三个文件复制到自己项目中去 App.vue </script> <style> import url(colorui/icon.css); import url(colorui/main.css); import url("colorui/animation.css");-webkit-keyframes show {…...
python做网站性能怎么样/广东企业网站seo报价
2019独角兽企业重金招聘Python工程师标准>>> <1>CALayer简介 1、CALayer一般作为UIView的容器而使用。 2、CALayer是一个管理者图片载体(image-based content)的层结构 3、直接修改单独创建出的CALayer的属性可以触发隐式动…...
网站开发三大元素/大型营销型网站制作
Servlet处理请求的流程: 1) 客户端在浏览器的地址栏中输入一个请求的URL,按回车后就向服务器端发起一个http request(由浏览器生成)。 2) 服务器端的Web Server首先接受到请求,并将请求转交给容器,容器会根据请求的URL去调用客户端要访问的Servlet。 3) …...
建设电影网站选服务器怎么选/河南省郑州市金水区
模型矩阵 观察矩阵 投影矩阵 奠定了三维理论的基础。 vertex data(顶点位置数据 x,y,z)经过 model matrix(模型矩阵)变换,即对顶点位置数据 x,y,z 进行平移、旋转、缩放,得到新的顶点位置,然后根…...
百度统计搜索词为什么有与网站不相关的词/工作手机
摘要:在当今信息化时代,大多数企业都需要网络支撑企业的ICT运行,提升企业运行效率,针对企业网络中的网元设备(包括交换机,路由器,防火墙等),很多企业希望根据自身的业务特…...
有没有做兼职的网站/刷神马网站优化排名
nginx默认配置文件 nginx.conf 介绍: 全局配置user nginx;设置nginx服务的系统使用用户worker_processes 1;工作进程数(建议和CPU核心数保持一致) error_log /var/log/nginx/error.log warn;错误日志。 warn代表级别pid /var/run/…...
做旅游网站平台ppt/最佳的搜索引擎
描述适合3ePIC试验板,爱晶产品销售服务做的不好,好多C程序都是自己写的,不过汇编程序参考一下不错。;------------------------------------------------------------------------------------------;单双位变换显示实验参考程序注意…...