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

Redis缓存详解:内存淘汰和缓存的预热、击穿、雪崩、穿透的原理与策略

目录

缓存的概念

使用redis作为缓存

缓存更新策略

缓存淘汰策略

关于缓存常见问题及解决方案

缓存预热(Cache preheating)

缓存穿透(Cache penetration)

缓存雪崩(Cache avalanche)

缓存击穿(Cache breakdown)

缓存的概念

缓存和磁盘功能相似,同样是具有存储数据,写入数据,获取数据的特点。缓存相较于磁盘来说,传统缓存不具备持久化保存数据(redis提供持久化的功能),容量也远远小于磁盘的容量,但是却又着访问速度极快的特点。

例子:

行李箱和身上衣服的口袋分别可以看作磁盘和缓存,行李箱相较于口袋能够装下很多东西,但是从行李箱中拿东西确比较慢,而衣服口袋容量虽然很小,但是能很快把里面的东西拿出来。

使用redis作为缓存

通常在网站开发中我们会使用关系型数据库(例如MySQL)来存储数据,这种数据库虽然功能强大但有一个很大的缺陷,就是性能不高,一次查询消耗资源比较多,在面对高并发场景对于数据库的压力是很大的, 很容易就会使数据库服务器宕机。

解决数据库承担高并发的思路通常有两种:

开源

①提高单台数据库服务器的硬件配置,增强处理能力。

②引入更多机器设备,读写分离,分库分表,构建数据库机器,分散压力。

节流

引入缓存,在缓存中保存访问频繁的热点数据,降低直接对数据量访问的请求量(“二八定律”,20%的热点数据能满足80%的访问需求)。

Redis 就是⼀个用来作为数据库缓存的常见方案

客户端访问业务服务器, 发起查询请求。

业务服务器先查询 Redis, 看想要的数据是否在 Redis 中存在。如果已经在 Redis 中存在了,就直接返回,此时不必访问 MySQL 了。如果在 Redis 中不存在,再查询 MySQ。

注意:

缓存是用来加快 "读操作" 的速度的,如果是 "写操作",还是要老老实实写数据库,缓存并不能提高性能。

缓存更新策略

定期生成

每隔一段时间(根据实际需求进行配置),对于访问的数据频次进行统计,挑选出前N%的数据更新到缓存中。适用于一些对实时性要求不高,但访问频繁的数据

实时生成

设置好缓存的容量上限,在接收用户请求的过程中,存在缓存的数据就直接返回给用户,如果不存在则去数据库中查,再将结果写到redis缓存中。

当缓存中的容量已达上限,就需要根据不同的策略对旧数据进行淘汰删除。

缓存淘汰策略

FIFO (First In First Out) 淘汰最先进来的

把缓存中存在时间最久的 (也就是最先来的数据) 淘汰掉。

LRU (Least Recently Used) 淘汰最久未使用的

记录每个 key 的最近访问时间,把最近访问时间最老的 key 淘汰掉。

LFU (Least Frequently Used) 淘汰访问次数最少的

记录每个 key 最近⼀段时间的访问次数,把访问次数最少的淘汰掉。

Random 随机淘汰

从所有的 key 中抽取幸运儿被随机淘汰掉。

Redis 通过配置 maxmemory-policy 来决定淘汰策略:

  • volatile-lru:淘汰设置了过期时间的 key 中最久未使用的

  • allkeys-lru:淘汰最久未使用的 key

  • volatile-lfu:淘汰设置了过期时间的 key 中访问次数最少的

  • allkeys-lfu:淘汰访问次数最少的 key

  • volatile-random:随机淘汰设置了过期时间的 key

  • allkeys-random:随机淘汰 key

  • volatile-ttl:淘汰设置了过期时间,即将过期的 key

  • noeviction:超出内存后,写操作报错(默认策略)

关于缓存常见问题及解决方案

缓存预热(Cache preheating)

缓存预热指的是,在服务上线/重启或热点产生前,主动把数据写入缓存,避免上线瞬间大量穿透 mysql。

成因:

对于定期生成的情况不涉及预热,主要是针对实时生成下需要进行缓存预热。在redis服务器首次接入后,服务器里还没有数据,此时如果接收了客户端发来的大量请求,缓存命中失败就会直接打给mysql。

解决方式

把定期生成和实时生成结合一下,先通过离线的方式,统计热点数据,将热点数据导入redis中。

缓存穿透(Cache penetration)

缓存穿透指的是,在查询某个key时,redis中没有,而mysql中也没有,这个key也不会被更新到redis中,如果这样的请求很多也会给mysql带来很大压力。

成因:

  1. 业务涉及不合理,可能缺少必要的参数检验环节,导致非法的key也被进行查询了。

  2. 操作失误,将数据库部分数据勿删了。

  3. 黑客恶意攻击。

解决方式:

  1. 当发现这个key在redis和mysql上都不存在时,任然写入redis,将value值设为一个非法值(例如“”)。

  2. 引入布隆过滤器,将合法的key预装到布隆过滤器中,请求先询问布隆过滤器,不存在就直接返回,不去访问mysql。

缓存雪崩(Cache avalanche)

缓存雪崩指的是,由于在短时间内,redis上大规模的key失效,导致缓存命中率直线下降,打到mysql的请求激增压力迅速上升,引发mysql宕机。

成因:

  1. redis 上的大量的 key同时过期。

  2. redis 节点重启或挂了

  3. 缓存被清空或缓存容量不足导致大规模淘汰

解决方式:

  1. 设置key的过期时间随机化,避免同一时刻过期。

  2. 加强监控报警,提高redis集群的可用性。

缓存击穿(Cache breakdown)

缓存击穿指的是,某个热点的 key 在过期瞬间产生大量请求去 mysql,短时间内对该单key的mysql访问量激增。与雪崩区别,雪崩是大量 key 同时过期,而击穿是单 key(或少数几个热 key)的问题。

成因:

某个热点key设置了过期时间,过期后仍然有大量访问。

解决方式:

  1. 将热点数据设置为永不过期。

  2. 进行必要的降级服务,访问数据库的的时候使用分布式锁,限制同时请求数据库的并发数。

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

相关文章:

  • 深入理解C++多态:从概念到实现
  • AudioLLM
  • 人工智能-python-特征选择-皮尔逊相关系数
  • 第15届蓝桥杯Scratch选拔赛初级及中级(STEMA)2023年12月17日真题
  • Python爬虫实战:构建国际营养数据采集系统
  • 非常简单!从零学习如何免费制作一个lofi视频
  • 【GitHub小娱乐】GitHub个人主页ProFile美化
  • 怎么选择和怎么填写域名解析到 阿里云ECS
  • 【Redis】Redis-plus-plus的安装与使用
  • 【pyqt5】SP_(Standard Pixmap)的标准图标常量及其对应的图标
  • elementui cascader 远程加载请求使用 选择单项等
  • AcWing 4579. 相遇问题
  • 生物多样性智慧化监测平台
  • 麒麟linux服务器搭建ftp服务【经典版】
  • 本地WSL部署接入 whisper + ollama qwen3:14b 总结字幕
  • 量化投资初探:搭建比特币智能交易机器人
  • 当AI成为语言桥梁:Seq2Seq的机器翻译革命
  • [CUDA] CUTLASS | `CuTe DSL` 创新
  • C# 使用iText获取PDF的trailer数据
  • 基于springboot+vue开发的校园食堂评价系统【源码+sql+可运行】【50809】
  • Baumer高防护相机如何通过YoloV8深度学习模型实现输电线路塔电缆检测分割(C#代码UI界面版)
  • 《Resolving tissue complexity by multimodal spatial omics modeling with MISO》
  • Python人工智能matplotlib中markers属性介绍
  • 【高等数学】第八章 向量代数与空间解析几何——第四节 空间直线及其方程
  • ABP VNext + Apache Kafka Exactly-Once 语义:金融级消息一致性实战
  • Linux用户和组管理及Apache服务安装
  • 浅谈 VM 桥接模式:让虚拟机像真实电脑一样接入网络
  • Go语言实战案例:表单提交数据解析
  • CMU-15445(8)——PROJECT#3-Query Execution-Task#1
  • 前端工程化:从构建工具到性能监控的全流程实践