当前位置: 首页 > news >正文

缓存穿透+缓存雪崩+缓存击穿(解决方法+实战)

声明:这是我根据黑马程序员视频做的学习笔记!(融入了自己的理解)感兴趣的可以去看原视频!

https://www.bilibili.com/video/BV1cr4y1671t/?spm_id_from=333.337.search-card.all.click

那么接下来开始我的博客

缓存穿透

产生原因:

缓存穿透是指客户端请求的数据再缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库,给数据库带来巨大压力

场景: 不怀好意的人 用多线程的形式去查询一个id不存在的信息,redis未命中,mysql中也没有 此时会给用户返回null值,线程继续用null 去查询信息,就会搞垮数据库

解决方案:

1.缓存null值(被动解决)

redis会将不存在的id存入缓存,就会阻挡访问mysql,比较暴力

优点:简单

缺点:额外的内存消耗,可能造成短期的不一致

2.布隆过滤(实际是种算法,依旧是被动姐u额):

布隆过滤器 底层是一个Byte[]数组,里面存的是二进制位

判断数据是否存在时,实际上是把这些数据基于某种哈希算法,再将哈希值转换成二进制位保存到布隆过滤器里,判断是否存在的是否就比较01二进制,

这种存在是概率上的问题,如存准确率达不到100%,存在可能不存在,但不存在真的不存在!

优点:空间占用非常的小

缺点:实现复杂,存在误判

3.雪花算法(主动避免缓存穿透)

解决商铺查询的缓存穿透问题

核心代码:

 @Overridepublic Result queryById(Long id) {//1,从redis查询商铺缓存String shopJson = stringRedisTemplate.opsForValue().get(CACHE_SHOP_KEY+id);//2.判断是否存在,并且shopJson不是null或" "if (StrUtil.isNotBlank(shopJson)) {//3.直接返回Shop shop = JSONUtil.toBean(shopJson, Shop.class);return Result.ok(shop);}//判断是是否是空值,若判断条件成立,此时shopJson只能是" "if(shopJson != null){return Result.fail("该店铺不存在");}//4.不存在,根据id查询数据库Shop shop = getById(id);//5.数据库不存在则返回错误if (shop == null) {stringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY+id,"",CACHE_NULL_TTL,TimeUnit.MINUTES);return Result.fail("店铺不存在");}//6,数据库若存在,将数据库写入redisstringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY+id,JSONUtil.toJsonStr(shop), RedisConstants.CACHE_SHOP_TTL, TimeUnit.MINUTES);//7.返回return Result.ok(shop);}

缓存雪崩

缓存雪崩是指同一时间段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。

解决方案:

1.给不同的key的TTL添加随机值,(将key失效时间分散开来,避免同时失效)

2.利用Redis集群提高服务的可用性(避免redis宕机)

3.非缓存业务添加降级限流策略

4.给业务添加多级缓存

缓存击穿

缓存击穿问题也是热点Key问题,就是一个被高并发访问把那个且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击。

解决方案:

1.互斥锁

2.逻辑过期

实际上添加这个把这个key-value添加到缓存之后就永远不会过期,我们只是在value上添加了一个逻辑及过期时间,每次线程访问缓存的时候就可以判断逻辑上过没过期(避免大量的请求直接落到数据库),那过期了怎么办,为了解决互斥锁的互相等待问题,当一个线程发现逻辑时间过期,就会加锁

,但是它会创建一个新的线程去做查询数据库,重写缓存,重置逻辑时间的操作,其他线程发现,缓存被加锁,先使用旧数据。

二者对比

基于互斥锁解决缓存击穿问题

流程图:

获取锁命令:setnx lock 操作名(设置有效期,兜底方案,防止某些情况 del lock不运行,迟迟不释放锁)

释放锁命令:del lock

核心代码:

public Shop queryWithMutex(Long id) {//1,从redis查询商铺缓存String key = CACHE_SHOP_KEY + id;String shopJson = stringRedisTemplate.opsForValue().get(key);//2.判断是否存在,并且shopJson不是null或" "if (StrUtil.isNotBlank(shopJson)) {//3.直接返回Shop shop = JSONUtil.toBean(shopJson, Shop.class);return shop;}//判断是是否是空值,若判断条件成立,此时shopJson只能是" "if(shopJson != null){return null;}//4.实现缓存重建//4.1获取互斥锁String lockKey = "Lock:"+key;Shop shop = null;try {boolean isLock = tryLock(lockKey);//4.2判断是否获取成功if(!isLock){//4.3如果失败则休眠 并重试Thread.sleep(50);//休眠后重试return queryWithMutex(id);}//4.4如果成功 根据id查询数据库shop = getById(id);//**模拟重建的延迟Thread.sleep(1000);//5.不存在,则返回错误if (shop == null) {stringRedisTemplate.opsForValue().set(key, "", 2, TimeUnit.MINUTES);return null;}//6,数据库若存在,将数据库写入redisstringRedisTemplate.opsForValue().set(key,JSONUtil.toJsonStr(shop), RedisConstants.CACHE_SHOP_TTL, TimeUnit.MINUTES);} catch (InterruptedException e) {throw new RuntimeException(e);}finally {unlock(lockKey);}return shop;}
 @Overridepublic Result queryById(Long id) {//缓存穿透//Shop shop = queryWithPassThrough(id);//互斥锁解决缓存击穿Shop shop = queryWithMutex(id);if (shop == null) {return  Result.fail("店铺不存在");}return Result.ok(shop);}

http://www.dtcms.com/a/391370.html

相关文章:

  • Docker技术相对于虚拟机技术的优劣势对比!
  • MyBatis框架与参数详解
  • Confluent-Kafka-go 发布超过 1M 消息失败问题解决
  • 数字图像处理-函数矩阵
  • 基于 ST-Link 和 MDK-Keil 的 STM32 程序下载实验
  • 安防监控系统的架构与组成原理
  • 【前端】【threeJs】前端事件偏移问题完整总结
  • web:ts的类型兼容性
  • 黑盒测试:测试用例设计之场景法(流程图法)(模拟用户实际使用软件的场景来设计测试用例,适用于业务流程复杂的系统测试)基本流、备选流
  • Django + Vue3 前后端分离技术实现自动化测试平台从零到有系列 <第二章> 之 平台功能架构整理
  • 神经网络学习笔记14——高效卷积神经网络架构EfficientNet
  • Flutter实现滑动页面停留吸附
  • 【Linux】基本指令介绍
  • 爬虫逆向--Day22Day23--核心实战案例【荔枝网】【WASM学习】----待完成
  • 【软考-系统架构设计师】特定领域软件体系结构(DSSA)
  • idea git使用提示问题处理
  • 数据结构初阶——哈希表的实现(C++)
  • Problem: lab-week3- exercise01 Insertion sort
  • 金融级虚拟机安全:虚拟化平台5大安全风险与国产化防护实践
  • 可视化在智慧城市中的应用
  • C#实现高性能拍照(旋转)与水印添加功能完整指南
  • Pandas 2.x与PyArrow:深入探索内存优化与性能提升技巧
  • opencv之轮廓识别
  • lesson65:JavaScript字符串操作完全指南:从基础到高级实战
  • 【脑电分析系列】第19篇:深度学习方法(一):卷积神经网络(CNN)在EEG图像/时频图分类中的应用
  • 写文件的几种方法
  • 序列化与反序列化漏洞及防御详解
  • uniapp 锁定竖屏,固定竖屏,锁定屏幕
  • 论文解读 | Franka 机器人的 CRISP-ROS2 集成实践:适配学习型操作策略与遥操作
  • Redis数据库(二)—— Redis 性能管理与缓存问题解决方案指南