用互斥锁解决缓存击穿

我先说一下正常的业务流程:需要查询店铺数据,我们会先从redis中查询,判断是否能命中,若命中说明redis中有需要的数据就直接返回;没有命中就需要去mysql数据库查询,在数据库中查到了就返回数据并把该数据存入redis中,若mysql数据库中也查不到就返回null,并返回错误信息:该信息不存在。

代码是用springboot+mybatis plus +redis+mysql实现的。

想看最初的mapper,service,controller层代码,就是解决缓存击穿之前的代码的话,可以去我的缓存穿透文章中看看,里面有,这里就不在写一遍了。

 下面让我来简单解释一下什么是缓存击穿:

  缓存击穿问题也叫热点key问题,就是一个被高并发访问并且缓存重建业务复杂的存储在redis中的key突然失效,无数请求就会瞬间打到数据库造成巨大冲击。

 解决方法:有俩个

  一个是互斥锁:这个互斥锁只能有一个线程拿到,拿到互斥锁的线程才能去查询数据库,并写入redis缓存,期间其他查询该数据的线程会全进入等待。缺点:性能差,且存在死锁的可能。

 另一个是逻辑过期时间:这个是不给存入的key设置过期时间,而是将过期时间写入value中,时间过期后,一个线程获取互斥锁然后另开一个新线程去查询数据库,写入缓存并释放锁。而老线程直接返回查到的旧数据,期间其他获取互斥锁失败的线程查询也会返回旧数据。缺点:有额外的内存消耗,不保证数据一致性,实现优点复杂。这个另写一个文章来进行代码实现。本文章只说用互斥锁解决。

代码实现:

 互斥锁:实现互斥锁,我们用的是redis的setnx key value命令,该命令只有在key不存在时才会创建成功,若key已存在就会创建失败。

  我们先写一下获取互斥锁和释放锁的方法

private boolean tryLock(String key) {//参数分别是,key,value,过期时间,过期时间的单位//这里过期时间用的事先写的静态变量,10LBoolean flag = stringRedisTemplate.opsForValue().setIfAbsent(key, "1", LOCK_SHOP_TTL, TimeUnit.SECONDS);return BooleanUtil.isTrue(flag); //如果直接返回flag,当flag为null时,会做拆箱,报错空指针。}private void UnLock(String key) {stringRedisTemplate.delete(key);}

用互斥锁解决缓存击穿:

@Service
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Resourceprivate CacheClient cacheClient;public 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) {//1.从redis查询数据缓存String key = CACHE_SHOP_KEY + id;String shopJson = stringRedisTemplate.opsForValue().get(key);//2.判断是否存在if (StrUtil.isNotBlank(shopJson)) { //isNOtBlank方法只有有值字符串才会返回true,null和空值都会返回false//3.存在,返回Shop shop = JSONUtil.toBean(shopJson, Shop.class);return shop;}//shopJson不存在//判断查到的数据是否为空值(这个空值指的不是null,是空字符串)if (shopJson != null) {//返回错误信息return null;}//4实现缓存重建//4.1获取互斥锁String lockKey = LOCK_SHOP_KEY + id;boolean lock = tryLock(lockKey);//4.2判断是否获取成功Shop shop = null;try {if (!lock) {//4.3失败,休眠并重试Thread.sleep(50);return queryWithMutex(id);}//4.4成功,根据id查询数据库shop = getById(id);//模拟数据库重建的延时Thread.sleep(200);//5.不存在,返回错误if (shop == null) {//将空值缓存到redisstringRedisTemplate.opsForValue().set(key, "", CACHE_NULL_TTL, TimeUnit.MINUTES);return null;}//6.存在,写入redisstringRedisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(shop), CACHE_SHOP_TTL, TimeUnit.MINUTES);} catch (InterruptedException e) {throw new RuntimeException(e);} finally {//7.释放互斥锁UnLock(lockKey);}//8.返回return shop;}
}

下面让我们来用Jmeter测试一下:

 开启100个线程去测试,结果都成功了,然后我们去idea控制台看看查询了数据库几次

 由返回信息可知,只查询了一次数据库,所以解决缓存击穿成功。

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

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

相关文章

Unity DOTS技术(三)JobSystem+Burst+批处理

文章目录 一.传统方式二.使用JobSystemBurst方式三.批处理 在之前的例子中我们都中用的单线程与传统的编译器,下面我们试着使用JobSystem与打找Burst编译器来对比一下性能的差异. 一.传统方式 1.首先用传统方式创建10000个方块并让基每帧旋转 2.我们可以看到他的帧率是40 …

RBAC 模型梳理

1. RBAC 模型是什么 RBAC&#xff08;Role-Based Access Control&#xff09;即&#xff1a;基于角色的权限控制。通过角色关联用户&#xff0c;角色关联权限的方式间接赋予用户权限。 RBAC 模型由 4 个基础模型组成&#xff1a; 基本模型 RBAC0&#xff08;Core RBAC&#x…

面向AI应用开发实战分享 - 基础篇

“前端转AI&#xff0c;第一讲来了” 引言 如果你是一名前端开发&#xff0c;同时又对AI开发很感兴趣&#xff0c;那么恭喜你&#xff0c;机会来了。 如果不是也没关系&#xff0c;同样能帮大家了解AI应用的开发思路。 本文将带大家从面向AI开发的基础知识开始&#xff0c;再…

AlaSQL.js:用SQL解锁JavaScript数据操作的魔法

简介 先附上 github 地址 https://github.com/AlaSQL/alasql AlaSQL.js - JavaScript SQL database for browser and Node.js. Handles both traditional relational tables and nested JSON data (NoSQL). Export, store, and import data from localStorage, IndexedDB, or …

高德车道级安全预警再升级 10大场景全方位守护行车安全

今日起&#xff0c;2024年高考、端午节小长假相继到来&#xff0c;正值新一波出行高峰到来&#xff0c;高德地图车道级安全预警功能再次升级。升级后的车道级安全预警功能覆盖了10大安全风险较高的行车场景&#xff0c;全方位、超视距地为用户实时探测、预警行车风险&#xff0…

成都跃享未来教育咨询有限公司,值得信赖!

在浩渺的教育咨询市场中&#xff0c;成都跃享未来教育咨询有限公司以其独特的魅力和卓越的服务质量&#xff0c;成为了行业内的璀璨明星。作为一家致力于为学生提供全方位教育咨询服务的公司&#xff0c;成都跃享未来教育咨询有限公司始终坚持安全可靠的原则&#xff0c;为广大…

树莓派4B_OpenCv学习笔记4:测试摄像头_imread加载显示图像_imwrite保存图片

今日继续学习树莓派4B 4G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: Opencv 版本是4.5.1&#xff1a; 今日对之前的测试CSI摄像头函数进行一些理解说明&#x…

降噪是什么意思?视频如何降噪?一文了解全部

在视频制作的过程中&#xff0c;我们经常会遇到噪音问题&#xff0c;这些噪音可能来自拍摄环境、录制设备或其他源头。然而&#xff0c;对于初学者来说&#xff0c;降噪是什么意思&#xff0c;以及如何有效地在视频中进行降噪可能是一些疑惑的问题。本文将深入解释降噪的概念&a…

【算法】深入浅出爬山算法:原理、实现与应用

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

echarts学习: 绘制双y轴折线图

前言 我们公司项目中的折线图大都是双y轴的&#xff0c;因为这些图表往往需要同时展示水位和流量这两种不同单位的数据&#xff0c;因此如何绘制双y轴折线图就是就是我所面临的首要问题。 1.如何绘制双y轴 将yAxis属性的值设置为一个数组&#xff0c;并在数组中添加两个axis对…

AI辅助论文:探索AI查重与AI降重技术

在科研领域&#xff0c;AI写作工具如同新一代的科研利器&#xff0c;它们能够极大提高文献查阅、思路整理和表达优化的效率&#xff0c;本质上促进了科研工作的进步。AI写作工具不仅快速获取并整理海量信息&#xff0c;还帮助我们精确提炼中心思想&#xff0c;显著提升论文写作…

0606 作业

#include <stdio.h> #include <string.h>typedef struct usr{char unm[21];char pwd[21]; }user;int main(int argc, const char *argv[]) {FILE* userfilefopen("./user_tible.txt","r");printf("输入username:");user u;scanf(&qu…

人工智能在肿瘤预后预测中的最新研究进展|顶刊精析·24-06-07

小罗碎碎念 今天要分享的文献主题&#xff0c;大家一定非常熟悉&#xff0c;因为绝大多数AI4cancer的文章都会提到它——预后预测&#xff0c;所以今天的文献主题是——人工智能肿瘤预后预测。 在正式开始分享之前&#xff0c;我想先带着大家梳理两个问题。解决了以下两个问…

【Python】实现极致:克服PyInstaller打包挑战,解决libpython3.10.so.1.0库丢失难题

【Python】实现极致&#xff1a;克服PyInstaller打包挑战&#xff0c;解决libpython3.10.so.1.0库丢失难题 大家好 我是寸铁&#x1f44a; 总结了一篇【Python】实现极致&#xff1a;克服PyInstaller打包挑战&#xff0c;解决libpython3.10.so.1.0库丢失难题✨ 喜欢的小伙伴可以…

ai智能全自动批量剪辑软件神器,让视频创作变得简单!

随着科技的飞速发展&#xff0c;人工智能技术在各个领域都取得了突破。在视频制作领域&#xff0c;AI智能全自动批量剪辑软件神器的出现&#xff0c;为视频创作者带来了前所未有的便利。接下来咱们详细介绍这款软件的特点和优势&#xff0c;以及它如何让视频创作变得更加简单。…

【网络安全的神秘世界】Kali安装中文输入法

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 今天就手把手教你如何在kali中安装和配置输入法 首先&#xff0c;打开终端&#xff0c;输入下面这行代码&#xff1a; # sudo apt install ibus ibus-pi…

【机器学习】Python与深度学习的完美结合——深度学习在医学影像诊断中的惊人表现

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 一、引言二、深度学习在医学影像诊断中的突破1. 技术原理2. 实际应用3. 性能表现 三、深度学习在医学影像诊断中的惊人表现1. 提高疾病诊断准确率2. 辅助制定治疗方案 四、深度学习对医疗行业的影响和推动作用 一、引言 随着…

网络安全领域六大顶级会议介绍:含会议介绍、会议地址及会议时间和截稿日期

**引言&#xff1a;**从事网络安全工作&#xff0c;以下六个顶会必须要知道&#xff0c;很多安全的前沿技术都会在如下会议中产生与公开&#xff0c;如下会议发表论文大部分可以公开下载。这些会议不仅是学术研究人员展示最新研究成果的平台&#xff0c;也是行业专家进行面对面…

[洛谷] 刷题栈 队列

目录 1.后缀表达式 2.表达式括号匹配 3.表达式求值 4.表达式的转换 5.机器翻译 1.后缀表达式 后缀表达式 - 洛谷 #include<iostream> #include<cstdio> using namespace std;int stk[100]; // 用于存储操作数的栈 int index 0; // 栈顶索引int main() {c…

C++开发基础之初探CUDA计算环境搭建

一、前言 项目中有使用到CUDA计算的相关内容。但是在早期CUDA计算环境搭建的过程中&#xff0c;并不是非常顺利&#xff0c;编写此篇文章记录下。对于刚刚开始研究的你可能会有一定的帮助。 二、环境搭建 搭建 CUDA 计算环境涉及到几个关键步骤&#xff0c;包括安装适当的 C…