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

Redis缓存管理机制

在当今快节奏的数字世界中,性能优化对于提供无缝的用户体验至关重要。缓存在提高应用程序性能方面发挥着至关重要的作用,它通过将经常使用或处理的数据存储在临时高速存储中来减少数据库负载并缩短响应时间,从而减少系统的延迟。Redis 是一种流行的内存数据存储,它提供了强大的缓存解决方案,可以显着提高应用程序的速度和效率。

在深入研究 Redis 缓存之前,让我们先了解缓存的基础知识。缓存涉及将经常访问或计算成本高昂的数据存储在快速且易于访问的位置(例如内存)中,以加快后续请求的速度。通过将数据存储在缓存中,应用程序可以避免从速度较慢的数据源(如数据库或外部 API)获取数据的需要,从而缩短响应时间并减少服务器负载。

Redis就像是一个超级快的小助手,站在数据库和应用程序之间(可以类比CPU,缓存,内存): Redis把数据存在内存里,就像把常用的东西放在手边一样,取用起来超快。相比之下,数据库就像是要去仓库找东西,慢很多。

使用 Redis 缓存时,请务必考虑以下内容:

确定要缓存的正确数据:并非所有数据都需要缓存。专注于缓存经常访问或生成计算成本高昂的数据。这包括不经常更改或可以在多个请求之间共享的数据。

设置过期策略:为缓存的数据确定适当的过期策略。这可确保缓存保持最新状态,并避免提供过时的数据。根据数据更新的频率和缓存数据所需的新鲜度设置过期时间。

实现缓存失效:当基础数据发生变化时,必须使相应的缓存条目失效或更新。这可以通过使用缓存失效触发器或监视数据源中的更改等技术来完成。

监控缓存性能:定期监控缓存性能,确保其有效性。密切关注缓存命中率、缓存未命中率和整体缓存利用率。监控可以帮助识别潜在的瓶颈或需要优化的领域。

针对高流量扩展 Redis:随着应用程序流量的增长,请考虑扩展 Redis 以处理增加的负载。这可能涉及使用 Redis 集群或复制在多个实例之间分配数据并提高读取和写入吞吐量。


缓存策略

a) 读取数据时:

  • 应用程序先问Redis:"嘿,你有这个数据吗?"

b) 写入数据时:

  • 如果Redis说"有",应用程序就直接用了,省去了问数据库的时间。
  • 如果Redis说"没有",应用程序就去数据库拿,然后告诉Redis:"保存一下,下次可能用得着。"
  • 应用程序更新数据库,然后告诉Redis:"嘿,数据更新了,你也更新一下。"

Redis的缓存策略主要涉及如何有效地管理缓存数据,以及如何保持缓存与数据源的一致性。让我们通过几个主要的缓存策略来深入了解:

1. Cache-Aside(旁路缓存)

想象Redis是一个效率极高的助手,而数据库是一个大型档案室。

工作流程

  • 读取数据:应用先查Redis,没有则去数据库取,然后放入Redis。
  • 写入数据:先更新数据库,再删除Redis中的对应键。

比喻:你想找一份文件。首先问助手(Redis)有没有,如果没有,你就去档案室(数据库)找,找到后给助手一份副本。当你需要更新文件时,先更新档案室的原件,然后告诉助手丢掉手中的旧副本。

优点:实现简单,Redis挂掉不影响系统正常运行。保证数据一致性。

缺点:第一次访问数据时会比较慢(称为"缓存穿透")。

2. Read/Write Through(读写穿透)

想象Redis现在变成了一个聪明的管家,所有的数据请求都必须经过他。

工作流程:

  • 读取数据:应用只和Redis交互,如果Redis没有数据,Redis负责从数据库读取并缓存。
  • 写入数据:应用把数据写入Redis,Redis负责同步更新到数据库。

比喻:你需要任何文件都告诉管家(Redis)。如果管家没有,他会去档案室(数据库)取,然后保存一份。当你要更新文件时,你把新文件交给管家,由他负责更新档案室。

优点:对应用层透明,应用不需要关心缓存的细节。数据一致性好。

缺点:增加了Redis的复杂度。可能会带来一定的性能损失。

3. Write-Behind Caching(异步写入)

把Redis想象成一个能暂存数据的智能助理。

工作流程:

  • 读取数据:与Read Through相同。
  • 写入数据:数据写入Redis后立即返回,Redis异步地将数据更新到数据库。

比喻:你把所有更新的文件都交给助理(Redis)。助理先记录下来,然后在空闲时统一更新到档案室(数据库)。

优点:写操作性能高。可以合并多次写操作,减少数据库压力。

缺点

数据丢失风险高,Redis宕机可能导致未同步的数据丢失。

数据一致性较弱,可能出现Redis和数据库数据不一致的情况。

4. 预加载策略

将Redis视为一个预习室。

工作流程:在系统启动或者定时任务中,主动将热点数据加载到Redis中。

比喻:在开始工作前,助理(Redis)主动去档案室(数据库)取出可能会用到的文件,放在手边以备不时之需。

优点:可以提前准备热点数据,提高访问速度。减少缓存穿透的情况。

缺点:需要提前预测热点数据,如果预测不准确可能会浪费资源。

5. 多级缓存策略

将Redis作为多级缓存系统中的一环。

工作流程
构建本地缓存(如应用服务器的内存) -> Redis -> 数据库的多级缓存架构。

比喻:你的办公室有个小抽屉(本地缓存),办公室外有个文件柜(Redis),大楼里有个档案室(数据库)。你会先看抽屉,然后是文件柜,最后才去档案室。

优点:进一步提高数据访问速度。减轻Redis的压力。

缺点:增加了系统复杂度。多级缓存一致性维护变得更加困难。

选择哪种缓存策略取决于你的具体需求,如对数据一致性的要求、系统的读写比例、性能需求等。在实际应用中,常常会综合使用多种策略来达到最佳效果。

redis把登入的数据都登录在了缓存内存中,避免了浪费时间的IO操作,但是随着数据量的增加redis存储的数据也会越来越多,所以接下来引入了过期策略


过期策略

设置过期策略:为缓存的数据确定适当的过期策略。这可确保缓存保持最新状态,并避免提供过时的数据。根据数据更新的频率和缓存数据所需的新鲜度设置过期时间。

Redis不会永远保存所有数据,它会给数据设置"保质期"。

  • 就像冰箱里的食物,过期了就自动扔掉。
  • 这样可以保证Redis里always存着新鲜的数据。

Redis 主要使用三种策略来管理过期的键:定时删除、惰性删除和内存淘汰。让我们用简单的比喻来理解这些概念。

1. 定时删除(主动删除)

想象 Redis 是一个图书管理员,而键就是借出去的书。

  • 工作原理:Redis 会为每个设置了过期时间的键都创建一个定时器,一旦到期,就立即删除。
  • 比喻:图书管理员给每本借出去的书都设置了一个闹钟。闹钟一响,他就立即去找到这本书并将其下架。
  • 优点:内存友好,过期键能被及时删除。
  • 缺点:CPU 不友好,可能会占用大量 CPU 时间去处理过期键。

实际上,Redis 用的是一种折中的策略:每秒进行 10 次过期键的检查,每次随机检查一些设置了过期时间的键,删除其中已过期的。

2. 惰性删除(被动删除)

想象 Redis 现在变成了一个懒惰的图书管理员。

  • 工作原理:Redis 不主动删除过期键,只有当你尝试访问一个键的时候,才会检查它是否过期,如果过期了就删除。
  • 比喻:图书管理员不主动检查书的借阅期。只有当有人来借书时,他才会检查这本书是否已经过期,如果过期了就将其下架。
  • 优点:CPU 友好,不会浪费 CPU 时间去检查未被使用的过期键。
  • 缺点:内存不友好,过期的键可能会在很长一段时间内占用内存。

3. 内存淘汰(内存不足时的被动删除)

想象 Redis 是一个书架空间有限的图书馆管理员。

  • 工作原理:当 Redis 的内存不足以容纳新的数据时,会根据选定的淘汰策略来删除一些键,为新数据腾出空间。
  • 比喻:当书架快满时,图书管理员会根据某种规则(比如最少使用、最近最少使用等)来决定哪些书要被移除,以便放入新书。

Redis 提供了几种内存淘汰策略:

a) noeviction:不淘汰任何数据,当内存不足时直接报错。

比喻:书架满了就不再接受新书,并告诉借书人"对不起,没位置了"。

b) allkeys-lru:从所有键中驱逐使用频率最少的键。

比喻:移除最长时间没人看过的书。

c) volatile-lru:从设置了过期时间的键中驱逐使用频率最少的键。

比喻:只在有"借阅期限"的书中,移除最长时间没人看过的书。

d) allkeys-random:随机驱逐键。

比喻:随机选择书本移除。

e) volatile-random:从设置了过期时间的键中随机驱逐。

比喻:在有"借阅期限"的书中随机选择移除。

f) volatile-ttl:驱逐快要过期的键。

比喻:优先移除快到"借阅期限"的书。

g) volatile-lfu 和 allkeys-lfu(Redis 4.0 新增):驱逐使用频率最低的键。

比喻:移除借阅次数最少的书。

实际应用中,Redis 会综合使用这些策略。定时删除和惰性删除是主要的过期键处理方式,而内存淘汰策略则是在内存紧张时的一种补充措施。选择合适的策略需要根据实际应用场景和需求来权衡。


缓存问题及它们的解决方案

1. 缓存击穿(Cache Penetration)

概念
缓存击穿指的是对于一个特定的高频热点key,在缓存过期的一刻,同时有大量的请求到达,这些请求同时发现缓存过期,于是同时去数据库中查询数据,导致数据库瞬间压力剧增。

比喻
想象一个热门商品在电商平台上的缓存刚好过期,而此时正值促销高峰,大量用户同时刷新页面,导致所有请求都直接冲向数据库。

解决方案

a) 互斥锁(Mutex Key)
   - 原理:第一个请求获取锁并从数据库加载数据,其他请求等待。
   - 实现:使用Redis的SetNX命令,成功设置则获取锁。
   - 优点:简单有效,保证只有一个请求会穿透到数据库。
   - 缺点:可能会造成某些请求的等待时间较长。

b) 设置热点数据永不过期
   - 原理:对于某些特别热点的数据,设置一个较长的过期时间或干脃不设置过期时间。
   - 实现:定期异步更新这些热点数据。
   - 优点:能有效防止缓存击穿。
   - 缺点:维护成本较高,需要额外的更新机制。

c) 提前更新缓存
   - 原理:在缓存即将过期前,异步更新缓存。
   - 实现:设置一个缓存刷新线程,检测即将过期的key并提前更新。
   - 优点:能有效避免缓存过期瞬间的压力。
   - 缺点:实现相对复杂,需要额外的系统资源。

2. 缓存雪崩(Cache Avalanche)

概念
缓存雪崩指的是大量缓存数据在同一时间集中过期,或者缓存服务器宕机,导致大量请求直接落到数据库上,引起数据库压力骤增,可能导致整个系统崩溃。

比喻
想象一场大型促销活动结束,所有商品的缓存同时失效,或者Redis服务器突然宕机,导致所有的请求如雪崩般冲向数据库。

解决方案

a) 均匀分布过期时间
   - 原理:在设置缓存过期时间时加入一个随机值,避免大量缓存同时过期。
   - 实现:过期时间 = 基础过期时间 + random(0, 300秒)
   - 优点:简单有效,易于实现。
   - 缺点:可能会稍微增加缓存不一致的概率。

b) 构建高可用的缓存集群
   - 原理:使用Redis Cluster或者哨兵模式,确保缓存系统的高可用性。
   - 实现:配置主从复制,并使用哨兵监控和自动故障转移。
   - 优点:大大提高系统的可用性和稳定性。
   - 缺点:增加了系统复杂度和维护成本。

c) 设置多级缓存
   - 原理:在Redis之上再增加一层本地缓存(如Guava Cache)。
   - 实现:请求首先访问本地缓存,miss后再访问Redis。
   - 优点:即使Redis完全不可用,系统仍能提供部分服务。
   - 缺点:增加了系统复杂度,且可能带来数据一致性问题。

d) 熔断降级机制
   - 原理:当检测到缓存服务不可用时,暂时屏蔽部分非核心功能,只提供最基本的服务。
   - 实现:使用类似Hystrix这样的熔断框架。
   - 优点:能够保护系统核心功能,防止整体崩溃。
   - 缺点:会暂时降低用户体验。

e) 预加载热点数据
   - 原理:系统启动时或者定时任务中提前加载热点数据到缓存。
   - 实现:编写脚本或定时任务,定期刷新热点数据的缓存。
   - 优点:可以有效减少缓存雪崩的影响范围。
   - 缺点:需要额外的维护成本,且可能会占用更多的缓存空间。

在实际应用中,通常会综合使用多种策略来防范缓存击穿和缓存雪崩。选择哪种方案或组合要根据具体的业务场景、系统架构和性能需求来决定。同时,良好的监控和告警机制也是必不可少的,可以帮助我们及时发现并解决问题。

3. 缓存失效( Cache Invalidation)

1. 避免缓存失效

a) 定时刷新策略

  • 原理:定期更新缓存中的数据,不依赖于单个数据变更。
  • 优点:简单可靠,适合变更频率较低的数据。
  • 缺点:可能存在短暂的数据不一致。

b) 基于消息队列的实时更新

  • 原理:数据变更时发送消息,专门的服务消费消息并更新缓存。
  • 优点:实时性高,系统解耦。
  • 缺点:需要额外的消息中间件,增加系统复杂度。

c) 双写一致性(Write-Behind)

  • 原理:更新数据时同时更新缓存和数据库,通过异步队列保证最终一致性。
  • 优点:保证缓存和数据库的最终一致性。
  • 缺点:实现复杂,需要处理各种异常情况。

2. 缓存监测方法

a) 健康检查

  • 原理:定期检查缓存服务的可用性和响应时间。
  • 作用:及时发现缓存服务的异常。

b) 缓存命中率监控

  • 原理:统计缓存的命中次数和未命中次数,计算命中率。
  • 作用:评估缓存效率,指导缓存策略优化。

c) 过期键监控

  • 原理:监控即将过期或已过期的键数量。
  • 作用:预防大规模缓存失效,避免缓存雪崩。

d) 内存使用监控

  • 原理:监控Redis的内存使用情况。
  • 作用:防止内存溢出,指导容量规划。

e) 慢查询日志分析

  • 原理:分析Redis的慢查询日志,找出性能瓶颈。
  • 作用:优化缓存查询性能,改进缓存策略。

参考

Redis Cache - GeeksforGeeks

【趣话Redis第一弹】我是Redis,MySQL大哥被我坑惨了!_哔哩哔哩_bilibili

相关文章:

Redis缓存管理机制

在当今快节奏的数字世界中,性能优化对于提供无缝的用户体验至关重要。缓存在提高应用程序性能方面发挥着至关重要的作用,它通过将经常使用或处理的数据存储在临时高速存储中来减少数据库负载并缩短响应时间,从而减少系统的延迟。Redis 是一种…...

初学嵌入式是弄linux还是单片机?

在开始前刚好我有一些资料,是我根据网友给的问题精心整理了一份「单片机的资料从专业入门到高级教程」, 点个关注在评论区回复“666”之后私信回复“666”,全部无偿共享给大家!!!1、先入门了51先学了89c52…...

【基础算法总结】分治—快排

分治—快排 1.分治2.颜色分类3.排序数组4.数组中的第K个最大元素5.库存管理 III 点赞👍👍收藏🌟🌟关注💖💖 你的支持是对我最大的鼓励,我们一起努力吧!😃😃 1.分治 分治…...

[C++]——同步异步日志系统(1)

同步异步日志系统 一、项⽬介绍二、开发环境三、核心技术四、环境搭建五、日志系统介绍5.1 为什么需要日志系统5.2 日志系统技术实现5.2.1 同步写日志5.2.2 异步写日志 日志系统: 日志:程序在运行过程中,用来记录程序运行状态信息。 作用&…...

python 第6册 辅助excel 002 批量创建非空白的 Excel 文件

---用教授的方式学习 此案例主要通过使用 while 循环以及 openpyxl. load_workbook()方法和 Workbook 的 save()方法,从而实现在当前目录中根据已经存在的Excel 文件批量创建多个非空白的Excel 文件。当运行此案例的Python 代码(A002.py 文件&#xff0…...

力扣61. 旋转链表(java)

思路:用快慢指针找到最后链表k个需要移动的节点,然后中间断开节点,原尾节点连接原头节点,返回新的节点即可; 但因为k可能比节点数大,所以需要先统计节点个数,再取模,看看k到底需要移…...

智慧园区综合平台解决方案PPT(75页)

## 智慧园区的理解 ### 从园区1.0到园区4.0的演进 1. 园区1.0:以土地经营为主,成本驱动,提供基本服务。 2. 园区2.0:服务驱动,关注企业成长,提供增值服务。 3. 园区3.0:智慧型园区&#xff…...

Python只读取Excel文件的一部分数据,比如特定范围的行和列?

如何只读取Excel文件的一部分数据,比如特定范围的行和列? 在Python中,如果你只想读取Excel文件的特定范围,可以使用以下方法: pandas: Pandas是一个强大的数据处理库,它有一个内置函数read_excel()用于读…...

快速入门FreeRTOS心得(正点原子学习版)

对于FreeROTS,我第一反应想到的就是通信里的TDM(时分多址)。不同任务给予分配不同的时间间隔,也就是任务之间在每个timeslot都在来回切换。 这里有重要的一点,就是中断要短小,优先级是自高到底进行打断。 …...

【博主推荐】HTML5实现简洁好看的个人简历网页模板源码

文章目录 1.设计来源1.1 主界面1.2 关于我界面1.3 工作经验界面1.4 学习教育界面1.5 个人技能界面1.6 专业特长界面1.7 朋友评价界面1.8 获奖情况界面1.9 联系我界面 2.效果和源码2.1 动态效果2.2 源代码 源码下载万套模板,程序开发,在线开发&#xff0c…...

Android应用安装过程

Android 系统源码源码-应用安装过程 Android 中应用安装的过程就是解析 AndroidManifest.xml 的过程,系统可以从 Manifest 中得到应用程序的相关信息,比如 Activity、Service、Broadcast Receiver 和 ContentProvider 等。这些工作都是由 PackageManage…...

Word中输入文字时,后面的文字消失

当在Word中输入文字时,如果发现后面的文字消失,通常是由以下3个原因造成的: 检查Insert键状态:首先确认是否误按了Insert键。如果是,请再次按下Insert键以切换回插入模式。在插入模式下,新输入的文字会插入…...

【LeetCode】合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 解题思路 水题,主要用于后面的链表的归并排序做了该题 AC代码 # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nex…...

分子AI预测赛Task1笔记

分子AI预测赛Task1笔记 实践步骤:跑通baseline → 尝试个人idea→尝试进阶baseline 一、跑通baseline 1、应当先下载数据库 下载相应的数据库 !pip install lightgbm openpyxl2、训练模型并预测结果 首先要导入相应的库和方法类,如pandas等 # 1. …...

ubuntu 安装并启用 samba

环境:ubuntu server 24.04 步骤如下: sudo apt update sudo apt install samba修改配置文件: sudo vi /etc/samba/smb.conf新增内容: [username]path /home/[username]available yesvalid users [username]read only nobrow…...

atcoder ABC 357-D题详解

atcoder ABC 357-D题详解 Problem Statement For a positive integer N, let VN​ be the integer formed by concatenating N exactly N times. More precisely, consider N as a string, concatenate N copies of it, and treat the result as an integer to get VN​. For…...

从单一到多元:EasyCVR流媒体视频汇聚技术推动安防监控智能升级

随着科技的飞速发展,视频已成为我们日常生活和工作中的重要组成部分。尤其在远程办公、在线教育、虚拟会议等领域,视频的应用愈发广泛。为了满足日益增长的视频需求,流媒体视频汇聚融合技术应运而生,它不仅改变了传统视频的观看和…...

Spring MVC数据绑定和响应——数据回写(二)JSON数据的回写

项目中已经导入了Jackson依赖,可以先调用Jackson的JSON转换的相关方法,将对象或集合转换成JSON数据,然后通过HttpServletResponse将JSON数据写入到输出流中完成回写,具体步骤如下。 1、修改文件DataController.java,在…...

怎么快速给他人分享图片?扫描二维码看图的简单做法

现在通过二维码来查看图片是一种很常见的方法,通过二维码来查看图片不仅能够减少对手机存储空间的占用,而且获取图片变得更加方便快捷,只需要扫码就能够查看图片,有利于图片的展现。很多的场景中都有图片二维码的应用,…...

【UML用户指南】-26-对高级行为建模-状态图

目录 1、概念 2、组成结构 3、一般用法 4、常用建模技术 4.1、对反应型对象建模 一个状态图显示了一个状态机。在为对象的生命期建模中 活动图展示的是跨过不同的对象从活动到活动的控制流 状态图展示的是单个对象内从状态到状态的控制流。 在UML中,用状态图…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...