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

Redis——缓存雪崩、击穿、穿透

缓存雪崩

大量缓存数据在同一时间过期或者Redis故障宕机时,若此时有大量请求,都会直接访问到数据库,导致数据库压力倍增甚至宕机。

大量数据同时过期解决方案:

1、均匀设置过期时间:

设置过期时间的时候可以追加一个随机数避免数据同一时间过期

2、互斥锁:

业务线程处理用户请求时,如果发现访问的数据不在Redis里,则加入互斥锁,保证同一时间只有一个业务线程访问数据库并构建缓存未获取到互斥锁的请求要么等待锁释放后获取缓存,要么返回指定值。注意:互斥锁应该设置过期时间避免获取锁的线程意外阻塞导致锁无法释放,造成无响应的情况。

3、后台更新缓存:

将更新缓存的工作交给后台线程进行更新

  • 第一种方式:后台频繁检测缓存是否有效,检测到缓存失效后(可能是内存资源不足被淘汰的)就马上访问数据库并更新到缓存。
  • 缺点:
    • 检测时间间隔不能太长,一般是毫秒级,有延迟问题
    • 频繁检测存在性能开销
  • 第二种方式:业务线程发现缓存失效后,通过消息队列发送一条信息通知后台线程更新缓存。后台线程收到消息后进行判断数据是否已被缓存,没有则访问数据库构建缓存
  • 优点:
    • 消息队列中可根据相同请求幂等性实现互斥锁的效果,无需加锁,所有请求都等待缓存构建或返回指定值即可。
    • 消息队列具有削峰作用,高并发时也能保证数据库正常运行

业务刚上线时我们就可以提前把数据缓存起来,而不是等待用户来触发缓存构建,这就是所谓的缓存预热

Redis宕机解决方案:

1、服务熔断或请求限流机制
  • 服务熔断机制暂停业务对缓存服务的访问,直接返回错误,而不是继续访问数据库,直到Redis恢复正常。
  • 请求限流机制只接收少部分请求发送到数据库进行处理,再多的请求就在入口直接拒绝服务,直到待Redis恢复正常
2、构建Redis高可靠集群

当前Redis宕机后依然可通过其他从节点获取缓存。

缓存击穿

缓存中的某个热点数据过期,此时大量请求直接访问到数据库。(缓存雪崩是多种多个数据请求缓存击穿是访问热点数据的大量请求

解决方案:

  • 互斥锁:保证同一时间只有应该业务线程共享缓存。
  • 后台异步更新缓存:不再给热点请求设置过期时间,或热点数据快过期时通知后台线程更新缓存并重新设置缓存时间。

缓存穿透

发生缓冲雪崩或击穿时,数据库中是有对应数据的,而缓冲穿透则是数据库中也无法获取到对应数据的情况。如果数据库无法获取数据就无法构建缓存,造成缓存失效。通常发生于业务误操作删除了数据恶意访问不存在的数据

解决方案:

1、限制非法请求:

在访问缓存或数据库前判断请求的参数是否合理,过滤不合理请求

2、缓存空值或默认值

若业务发现有缓存穿透的现象,可以针对查询数据在缓存中设置空值或者默认值

3、布隆过滤器

使用布隆过滤器快速判断数据是否存在,避免通过查询数据库来判断

布隆过滤器的实现:

初始值都为0的位图数组(Bitmap,连续二进制位序列)和N个哈希函数两部分组成。我们在写入数据库数据的同时对布隆过滤器做标记,这样后续的查询就可根据布隆过滤器快速判断数据是否存在。

过滤操作:
  • 第一步,使用N个哈希函数分别对数据进行哈希计算得到N个哈希值
  • 第二步,将第一步得到的N个哈希值对位图数组的长度进行取模得到每个哈希值的对应位置
  • 第三步,将每个哈希值在位图数组中的对应位置设为1

假设有一个长度为8的位图数组,3个哈希函数的布隆过滤器:

查询时,分别计算出数据N个哈希值对应的位置并判断是否全为1。只要有一个为0就说明数据不存在。

布隆过滤器也是存在哈希冲突的,哈希冲突时可能将不存在的查询数据误判为已存在(与数据库中存在的数据发生了哈希冲突)。但数据库中不存在的数据在布隆过滤器中就一定不存在

通过增加哈希函数的数量,可尽量减少因为哈希冲突发生误判的情况

相关文章:

  • WSL 安装 Debian 12 后,如何安装图形界面 X11 ?
  • 手撕四种常用设计模式(工厂,策略,代理,单例)
  • sudo apt update是什么意思呢?
  • STM32F10xx 参考手册
  • 从零开始理解Jetty:轻量级Java服务器的入门指南
  • JavaScript入门【2】语法基础
  • MATLAB学习笔记(六):MATLAB数学建模
  • Redis Sentinel如何实现高可用?
  • 机器学习——逻辑回归
  • C/C++之内存管理
  • 网络编程中的直接内存与零拷贝
  • 强化学习赋能医疗大模型:构建闭环检索-反馈-优化系统提升推理能力
  • chrome 浏览器插件 myTools, 日常小工具。
  • 【C++】string的使用【上】
  • spring -MVC-02
  • 相机Camera日志分析之十一:高通相机Camx hal预览1帧logcat日志process_capture_result详解
  • (C语言)超市管理系统 (正式版)(指针)(数据结构)(清屏操作)(文件读写)(网页版预告)(html)(js)(json)
  • Node.js 源码概览
  • 使用 Python 连接 Oracle 23ai 数据库完整指南
  • 黑马点评-用户登录
  • 人民日报和音:相信中国就是相信明天
  • 荣盛发展:新增未支付债务11.05亿元
  • 一条铺过11年时光的科学红毯,丈量上海科创的“长宽高”
  • “免签圈”扩容,旅游平台:今年以来巴西等国入境游订单显著增加
  • 创同期历史新高!1至4月全国铁路发送旅客14.6亿人次
  • 人民日报民生观:转人工客服,怎么这么难?