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

Redis机制-Redis缓存穿透,击穿,雪崩理解等问题的理解和学习

目录

一 缓存穿透问题

二 缓存击穿问题

三 缓存雪崩问题:


图1 正常的Redis缓存流程

一 缓存穿透问题

我们都知道Redis是一个存储键值对的非关系型数据库,那么当用户进行查询的时候,势必会从前端发起请求,从而数据从Redis缓存中进行查找,查找不到则会在数据库中进行查找。

那么此时就会出现一个问题,就是当有人恶意访问不存在的key时,此时Redis的缓存中没有该值,那么就会一致把请求发送到数据库中。当大量出现上述情况时,此时数据库的负载就会过大,从而发生缓存穿透的问题。

解决方案:

要解决上述问题,一般会使用布隆过滤器或者缓存null值的方法,来避免数据库被攻击。首先我们来讲讲布隆过滤器。

图2 布隆过滤器(详情请查看 布隆过滤器详解Blog)

布隆过滤器是搭建在访问Redis服务器之前的,布隆过滤器就是在请求到达Redis之前过滤掉一些Redis缓存中不存在的请求。

图3 位图

首先,请求访问Redis时会携带要访问的key值,此时布隆过滤器会使用不同的hash函数对该key进行哈希,并且存储在位图中,假如每一位都对上了,那么就说明Redis中存在该key那么就可以访问Redis服务器,否则就会直接返回null,从而避免了Redis缓存穿透的问题。

当然,布隆过滤器也会有缺点,就是出现误判的问题,如下图

图4 不同的id误判情况

id=3的数据是不存在的,但是经过不同的hash之后发现,对应的位置恰好为1,那么此时就会出现误判的问题。解决方法当然有,就是增加位图的长度,长度越长误判率就越小,但是此时也出现了额外的内存消耗。当布隆过滤器判断一个元素不存在时,就说明该元素是真的不存在,但是判断存在的时候,也不一定存在。

第二个方法就是在Redis中直接缓存key:null这个键值对,一般时间会设置到5分钟左右,从而避免数据库的压力。当然这样的方式就有些简单粗暴了。

二 缓存击穿问题

当一个热点的key被多个用户频繁访问时,此时如果该key处于过期并且重建的过程中,那么会面临多个请求一起发送到数据库的情况,那么此时就会对数据库造成极大的负载,此时就出现了缓存击穿的问题。

图 5 缓存击穿

针对该问题也有两种方案进行解决,互斥锁和逻辑过期

互斥锁:

图 6 互斥锁

互斥锁是通过对多个线程进行加锁操作从而避免缓存击穿问题的。大致流程如下:

1.当线程1查询缓存时,如果缓存未命中,那么此时就会获取到一把锁,然后去数据库中进行查询数据并且试图重建缓存。

2.线程2也刚好访问该key,它也想拿到锁对数据库进行查询,但是获取锁失败了,就休眠一会再试。

3.当线程1完成一系列操作以后,重建了缓存,此时线程2也可以获取到Redis新建的缓存,那么此时就缓存命中了,就避免了与数据库直接交互的过程,也就避免了缓存击穿的问题。

第二个方法就是逻辑过期

就是将热点的key不设置过期时间。

图 7 逻辑过期

如图:

1.当线程1查询数据时,会获取到互斥锁,然后返回过期数据

2.但是在此之间它还会开启一个新的线程2来重建缓存,重置逻辑过期时间

3.当线程2重写缓存时,线程3刚好来访问,那么线程3会返回一个过期的数据

4.当线程4来访问的时候,因为是在线程2释放锁之后进行的,所以线程4获取的是新的数据。

这就是逻辑过期的原理。

看到这里,其实肯定有疑问,为什么我不选择互斥锁,而选择逻辑过期呢?

其实这还和使用场景有关系,比如说,当写转账,或者京东,淘宝这种秒杀逻辑时,就需要数据的强一致性,那么就需要使用互斥锁,但是一些其他的场景,则有可能用历史的数据就可以完成。那么逻辑过期就可以解决这个问题。主要还是具体场景具体用法。

三 缓存雪崩问题:

听起来名字很可怕,雪崩,但是其实也是由于大量缓存的key同时失效或者Redis服务器宕机所带来的问题,请求会直接到达数据库,从而产生巨大的压力。

图8 缓存雪崩

解决方案:

1.给不同的key添加所及的TTL值:可以让不同的key不会同时达到过期时间。

2.利用Redis集群来提高服务的可用性:比如哨兵模式,主从模式等等

3.给缓存业务添加降级限流策略(系统保底策略。可以解决上面提到的三个问题)

4.添加多级缓存

相关文章:

  • Python面试宝典:Python中与数据库连接和操作相关的面试笔试题(1000加面试笔试题助你轻松捕获大厂Offer)
  • 神经网络的工程基础(一)——利用PyTorch实现梯度下降法
  • 基于STM32的自动宠物喂食器的Proteus仿真
  • x的平方根-力扣
  • [7] CUDA之常量内存与纹理内存
  • Java——图书管理系统万字详解(附代码)
  • 树莓派4B 有电但无法启动
  • 几种常用的配置文件格式对比分析——ini、json、xml、toml、yaml
  • 2024年5月20日优雅草蜻蜓API大数据服务中心v2.0.4更新
  • 26.synchronized和ReentrantLock的区别
  • 初步认识栈和队列
  • 网络安全等级保护:正确配置 Linux
  • 38、Flink 的窗口触发器(Triggers)详解
  • html5网页-浏览器中实现高德地图定位功能
  • 生产制造边角料核算说明及ODOO演示
  • 【Linux系统编程】快速查找errno错误码信息
  • Android Volley源码解析
  • Date型的使用
  • Docker 笔记(2):Dockerfile
  • exports和module.exports
  • input实现文字超出省略号功能
  • JavaScript中的对象个人分享
  • js中的正则表达式入门
  • Map集合、散列表、红黑树介绍
  • maya建模与骨骼动画快速实现人工鱼
  • Python中eval与exec的使用及区别
  • SegmentFault 2015 Top Rank
  • tensorflow学习笔记3——MNIST应用篇
  • 爱情 北京女病人
  • 产品三维模型在线预览
  • 第三十一到第三十三天:我是精明的小卖家(一)
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 基于组件的设计工作流与界面抽象
  • 检测对象或数组
  • 聊一聊前端的监控
  • 让你的分享飞起来——极光推出社会化分享组件
  • 使用Swoole加速Laravel(正式环境中)
  • 收藏好这篇,别再只说“数据劫持”了
  • 微信小程序--------语音识别(前端自己也能玩)
  • 优秀架构师必须掌握的架构思维
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • ​软考-高级-信息系统项目管理师教程 第四版【第14章-项目沟通管理-思维导图】​
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • ‌前端列表展示1000条大量数据时,后端通常需要进行一定的处理。‌
  • !!Dom4j 学习笔记
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (20)docke容器
  • (2024,Flag-DiT,文本引导的多模态生成,SR,统一的标记化,RoPE、RMSNorm 和流匹配)Lumina-T2X
  • (el-Date-Picker)操作(不使用 ts):Element-plus 中 DatePicker 组件的使用及输出想要日期格式需求的解决过程
  • (二)Pytorch快速搭建神经网络模型实现气温预测回归(代码+详细注解)
  • (附源码)spring boot球鞋文化交流论坛 毕业设计 141436
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (黑客游戏)HackTheGame1.21 过关攻略