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

【Redis】缓存预热、雪崩、击穿、穿透、过期删除策略、内存淘汰策略

Redis常见问题总结:

  • Redis常见问题总结
    • Redis缓存预热
    • Redis缓存雪崩
    • Redis缓存击穿
    • Redis缓存穿透
  • Redis 中 key 的过期删除策略
    • 数据删除策略
  • Redis内存淘汰策略
    • 一、Redis对过期数据的处理
      • (一)相关配置
      • (二)内存淘汰流程
      • (三)动态改配置命令
    • 二、内存淘汰策略的种类及特点
      • (一)Redis 4.0以前的策略
      • (二)Redis 4.0以后增加的策略
    • 三、常见的淘汰算法
      • (一)FIFO算法(先进先出)
      • (二)LRU算法(最近最少使用)
      • (三)LFU算法(最不常使用)
      • (四)LRU和LFU的选择
    • 总结

Redis常见问题总结

Redis缓存预热

“宕机”服务器启动后迅速宕机,指的是服务刚上线由于Redis中没有任何数据,导致大量请求访问数据库,主从之间数据吞吐量较大,数据同步操作频度较高。

而缓存预热解决的就是,在系统启动前,提前将相关的数据直接加载到缓存系统。避免用户在请求的时候,先查询数据库,再将数据库的查询到的数据缓存到Redis的问题。用户可以直接查询事先被预热的缓存数据。

解决方案:

  • 准备工作:
    • 日常例行统计数据访问记录,统计访问频度较高的热点数据。
    • 将统计结果中的数据分类,根据级别,Redis优先加载级别较高的热点数据
  • 实施:
    • 使用脚本程序固定触发数据预热过程
    • 如果条件允许,使用CDN(内容分发网络),效果会更好

Redis缓存雪崩

缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求到达数据库,带来巨大压力。【这里指的是同一批key的过期时间相同或者Redis服务挂掉】

解决方案:

  • 给不同的Key的TTL添加随机值
  • 利用Redis集群提高服务的可用性
  • 给缓存业务添加降级限流策略
  • 给业务添加多级缓存

Redis缓存击穿

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

常见的解决方案有两种:

  • 互斥锁
  • 逻辑过期

互斥锁:

逻辑过期:

Redis缓存穿透

缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库

常见两种解决方案:

  • 缓存空对象
  • 布隆过滤器

Redis 中 key 的过期删除策略

数据删除策略

什么是过期数据?

Redis是一种内存级数据库,所有数据均存放在内存中,内存中的数据可以通过TTL指令获取其状态

  • XX :具有时效性的数据
  • -1 :永久有效的数据
  • -2 :已经过期的数据或被删除的数据或未定义的数据

注意:过期的数据真的删除了吗?不是的

删除策略比对

1. 定时删除 节约内存,无占用 不分时段占用CPU资源,频度高拿时间换空间

2. 惰性删除 内存占用严重延时执行,CPU利用率高拿空间换时间

3. 定期删除 内存定期随机清理每秒花费固定的CPU资源维护内存随机抽查,重点抽查

Redis的过期键的删除策略是指当Redis中的缓存的key过期了,Redis要如何处理。
Redis中提供了三种删除策略:
1.定时删除
当放入数据后,设置一个定时器,当定时器读秒完毕后,将对应的数据从dict中删除。
优点: 内存友好,数据一旦过期就会被删除
缺点: CPU不友好,定时器耗费CPU资源,并且频繁的执行清理操作也会耗费CPU资源。用时间换空间
2.惰性删除
当数据过期的时候,不做任何操作。当访问数据的时候,查看数据是否过期,如果过期返回null,并且将数据从内存中清除。如果没过期,就直接返回数据。
优点: CPU友好,数据等到过期并且被访问的时候,才会删除。
缺点: 内存不友好,会占用大量内存。用空间换时间
3.定期删除
定期删除是定时删除和惰性删除的折中方案。每隔一段时间对redisServer中的所有redisDb的expires依次进行随机抽取检查。
Redis中有一个server.hz定义了每秒钟执行定期删除的次数,每次执行的时间为250ms/server.hz。Redis中会维护一个current_db变量来标志当前检查的数据库。current_db++,当超过数据库的数量的时候,会重新从0开始。
定期检查就是执行一个循环,循环中的每轮操作会从current_db对应的数据库中随机依次取出w个key,查看其是否过期。如果过期就将其删除, 并且记录删除的key的个数。如果过期的key个数大于w25%,就会继续检查当前数据库,当过期的key小于w25%,会继续检查下一个数据库。当执行时间超过规定的最大执行时间的时候,会退出检查。一次检查中可以检查多个数据库,但是最多检查数量是redisServer中的数据库个数,也就是最多只能从当前位置检查一圈。

Redis内存淘汰策略

一、Redis对过期数据的处理

Redis的内存淘汰机制主要是用于在Redis用于缓存的内存不足时,处理需要新写入且需申请额外空间的数据。

(一)相关配置

  1. redis.conf中:
    • 配置maxmemory <bytes>,用于设置Redis的最大内存空间。若不设定该参数,默认无限制,通常会设定为物理内存的四分之三。
    • 配置maxmemory-policy noeviction,用于设置淘汰策略,默认为noeviction

(二)内存淘汰流程

  1. 客户端发起需要申请更多内存的命令(如set)。
  2. Redis检查内存使用情况,若已使用内存大于maxmemory,则根据用户配置的不同淘汰策略来淘汰内存(key),以换取一定的内存。
  3. 若上述步骤均无问题,则该命令执行成功。

(三)动态改配置命令

Redis支持动态改配置,无需重启。

  • 设置最大内存:config set maxmemory 100000
  • 设置淘汰策略:config set maxmemory-policy noeviction

二、内存淘汰策略的种类及特点

(一)Redis 4.0以前的策略

  1. noeviction:当内存使用超过配置时会返回错误,不会驱逐任何键。(默认选项,一般不选用)
  2. allkeys-lru:当内存不足以容纳新写入数据时,在整个键空间中,移除最近最少使用的key。(最常用)
  3. volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。
  4. allkeys-random:当内存不足以容纳新写入数据时,在整个键空间中,随机移除某个key。
  5. volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。
  6. volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。

(二)Redis 4.0以后增加的策略

  1. volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的键。
  2. allkeys-lfu:从所有键中驱逐使用频率最少的键。

内存淘汰策略可通过配置文件修改,redis.conf对应的配置项是maxmemory-policy,修改对应的值即可。

三、常见的淘汰算法

(一)FIFO算法(先进先出)

  1. 思想
    • 基于队列的先进先出原则,最先进入的数据会被最先淘汰掉,是最简单、最公平的思想。
  2. 实现
    • 维护一个FIFO队列,按照时间顺序将各数据(已分配页面)链接起来组成队列,并将置换指针指向队列的队首。进行置换时,把置换指针所指的数据(页面)顺次换出,并把新加入的数据插到队尾即可。
  3. 缺点
    • 会导致缺页率增加。随着分配页面的增加,被置换的内存页面往往是被频繁访问的,因此FIFO算法会使一些页面频繁地被替换和重新申请内存,从而导致缺页率增加。由于缺页率会随着分配页面的增加而增加,使得redis的开销也逐渐增加,所以这种算法已不再使用。

(二)LRU算法(最近最少使用)

  1. 思想
    • 最近最少使用的会被优先淘汰。如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小。当空间满时,最久没有访问的数据最先被淘汰掉。
  2. 实现
    • 用双向链表(LinkedList)+哈希表(HashMap)实现(链表用来表示位置,哈希表用来存储和查找),在Java里有对应的数据结构LinkedHashMap
  3. 缺点
    • 在需要淘汰时,只是随机选取有限的key进行对比,排除掉访问时间最久的元素,不能选择整个候选元素的最优解,只是局部最优。默认随机选取的key的数目为5,在配置文件redis.conf中由maxmemory_samples属性的值决定,采样数量越大越接近于标准LRU算法,但也会带来性能的消耗。
    • 在Redis 3.0以后增加了LRU淘汰池,进一步提高了与标准LRU算法效果的相似度。淘汰池即维护的一个数组,数组大小等于抽样数量maxmemory_samples,在每一次淘汰时,新随机抽取的key和淘汰池中的key进行合并,然后淘汰掉最旧的key,将剩余较旧的前面5个key放入淘汰池中待下一次循环使用。假如maxmemory_samples = 5,随机抽取5个元素,淘汰池中还有5个元素,相当于变相的maxmemory_samples = 10,所以进一步提高了与LRU算法的相似度。

(三)LFU算法(最不常使用)

  1. 思想
    • 如果一个数据在最近一段时间很少被访问到,那么在将来它被访问的可能性也很小。当空间满时,最小频率访问的数据最先被淘汰。
  2. 实现及问题解决
    • 为每个key维护一个计数器,每次key被访问时,计数器增大,计数器越大,则认为访问越频繁。但存在以下问题:
      • 可能存在某个key在开始一个小时内有100万的访问量,但之后一小时内访问量为0,而在第二个小时内另一个key的访问量达到20万,此时第二个小时内key1会优先于key2被淘汰,尽管key2在该小时内访问量更大。
      • 当新加入的key,由于没有被访问过,初始计数器为0,若此时触发淘汰机制,会把最先添加的key最先淘汰掉。
    • 解决方案:在LFU算法中维护了一个24bit的字段,被分成16 bits与8 bits两部分。第一部分(高16 bits)用来记录计数器的上次缩减时间,时间戳,单位精确到分钟。第二部分(低8 bits)用来记录计数器的当前数值,该数值反映访问频率,而非次数。
    • redis.conf配置文件中,lfu-log-factor用来调整计数器counter的增长速度,lfu-log-factor越大,counter增长越慢。lfu-decay-time是一个以分钟为单位的数值,用来调整counter的缩减速度。

(四)LRU和LFU的选择

需要根据业务权衡到底是选择淘汰最近最少使用(LRU)还是选择最不经常使用(LFU)。总的来说,无论是LRU、LFU、TTL还是Random都是近似算法来实现的,在可靠性和性能上做了一定的平衡。在业务中应主动删除没有价值的数据,或者更新某些key的过期时间等来提高Redis的性能和空间,不能过分依赖于淘汰策略。

(此处可根据需要插入相关图片,例如LRU和LFU算法的示意图等,假设插入了一张LRU算法的示意图,如下所示)

LRU算法示意图

总结

Redis的内存淘汰策略的选取并不会影响过期的key的处理。内存淘汰策略用于处理内存不足时需要申请额外空间的数据;过期策略用于处理过期的缓存数据。要根据实际业务场景和需求合理选择内存淘汰策略,并结合主动的数据管理操作来优化Redis的性能和内存使用。

相关文章:

【Redis】缓存预热、雪崩、击穿、穿透、过期删除策略、内存淘汰策略

Redis常见问题总结&#xff1a; Redis常见问题总结Redis缓存预热Redis缓存雪崩Redis缓存击穿Redis缓存穿透 Redis 中 key 的过期删除策略数据删除策略 Redis内存淘汰策略一、Redis对过期数据的处理&#xff08;一&#xff09;相关配置&#xff08;二&#xff09;内存淘汰流程&a…...

【LeetCode】每日一题 2024_10_15 三角形的最大高度(枚举、模拟)

前言 每天和你一起刷 LeetCode 每日一题~ LeetCode 启动&#xff01; 题目&#xff1a;三角形的最大高度 代码与解题思路 久违的简单题 这道题读完题目其实不难想到有两条路可以走&#xff1a; 1、题目很明显只有两种情况&#xff0c;枚举是第一个球是红球还是蓝球这两种情…...

2024版最新网络安全工程师入门教程(非常详细)从零基础入门到精通,看完这一篇就够了

前言 想要成为网络安全工程师&#xff0c;却苦于没有方向&#xff0c;不知道从何学起的话&#xff0c;下面这篇 网络安全入门 教程可以帮你实现自己的网络安全工程师梦想&#xff0c;如果想学&#xff0c;可以继续看下去&#xff0c;文章有点长&#xff0c;希望你可以耐心看到…...

vue中关于router.beforeEach()的用法

router.beforeEach()是Vue.js中的路由守卫&#xff0c;用于在路由跳转前进行校验、取消、重定向等操作。 基本使用&#xff1a; const router new VueRouter({ ... })router.beforeEach((to, from, next) > {// ... }) to: 即将要进入的目标路由对象 from: 当前导航正要…...

C++模板初阶,只需稍微学习;直接起飞;泛型编程

&#x1f913;泛型编程 假设像以前交换两个函数需要&#xff0c;函数写很多个或者要重载很多个&#xff1b;那么有什么办法实现一个通用的函数呢&#xff1f; void Swap(int& x, int& y) {int tmp x;x y;y tmp; } void Swap(double& x, double& y) {doubl…...

【数据结构 | 红黑树】红黑树的性质和插入结点时的调整

文章目录 红黑树红黑树插入时的调整&#xff1f;1. 插入结点是根结点2. 插入结点的叔叔是红色3. 插入结点的叔叔是黑色LL 型RR型LR型RL型 红黑树 前提&#xff1a;二叉搜索树&#xff08;左 < 根 < 右&#xff09;—— 左根右根和**叶子&#xff08;NULL&#xff09;**都…...

mysql学习教程,从入门到精通,SQL导入数据(44)

1.SQL 导出数据 以下是一个关于如何使用 SQL 导出数据的示例。这个示例将涵盖从一个关系数据库管理系统&#xff08;如 MySQL&#xff09;中导出数据到 CSV 文件的基本步骤。 1.1、前提条件 你已经安装并配置好了 MySQL 数据库。你有访问数据库的权限。你知道要导出的表名。…...

【SpringAI】(二)让你的Java程序接入大模型——适合Java宝宝的大模型应用开发

开始之前&#xff0c;如果你对大模型完全没了解过&#xff0c;建议阅读之前的大模型入门文章&#xff1a; 【SpringAI】&#xff08;一&#xff09;从实际场景入门大模型——适合Java宝宝的大模型应用开发 那么今天就开始写一个基于Spring AI程序的HelloWord!将大模型接入到咱…...

音频剪辑在线工具 —— 让声音更精彩

你是否曾梦想过拥有自己的声音创作空间&#xff0c;却苦于复杂的音频编辑软件&#xff1f;接下来&#xff0c;让我们一同揭开这些音频剪辑在线工具的神秘面纱&#xff0c;看看它们如何帮助你实现从录音到发布的无缝衔接。 1.福昕音频剪辑 链接直达>>https://www.foxits…...

​http短连接和长连接​

参考短连接和长连接 短连接&#xff1a;客户端向服务器每进行一次Http操作&#xff0c;都需建立一次连接&#xff0c;任务完成后&#xff0c;断开连接&#xff1b;长连接&#xff1a;建立长连接后&#xff0c;传输数据的连接将不会中断&#xff0c;客户端每次访问服务器时都会…...

日志分析删除

日志分析 场景 运维嫌弃生产环境打印日志过多&#xff0c;而且日志存储需要费用&#xff0c;让我们减少打印日志大小&#xff0c;所以需要分析日志在哪里打印的过多 解决方案 读取生产日志文件&#xff0c;统计分析打印日志的地方&#xff0c;最后删除代码中打印日志的地方…...

DART: Implicit Doppler Tomography for Radar Novel View Synthesis 笔记

Link&#xff1a;https://wiselabcmu.github.io/dart/ Publish&#xff1a; 2024CVPR Abstract DART主要任务就是用来合成雷达距离多普勒图像range-droppler&#xff0c;可用于生成高质量的断层扫描图像。 Related Work 1 Radar Simulation 基于模型的方法 任务&#xff…...

redis-cli执行lua脚本

连接redis服务器命令 redis-cli -h 10.10.xx.xx -p 6380 -a password执行lua脚本传递KEY VALUE redis-cli -h 10.10.xx.xx -p 6380 -a password key1 key2 , arg1 arg2key和参数通过逗号分割&#xff0c;逗号前后必须有一个空格 如下执行lua脚本示例&#xff1a; -- script.…...

MySQL9的3个新特性

【图书推荐】《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;》-CSDN博客 《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;&#xff08;数据库技术丛书&#xff09;》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) 本文讲解MySQL9的3个新特性&…...

《网络基础之 HTTP 协议:状态码含义全解析》

《网络基础之 HTTP 协议&#xff1a;状态码含义全解析》 在网络通信的浩瀚世界中&#xff0c;HTTP 协议犹如一座坚实的桥梁&#xff0c;连接着客户端与服务器。而其中的状态码&#xff0c;则是这座桥梁上的重要标识&#xff0c;为双方的交互提供了关键的反馈信息。 一、状态码…...

java真的正在越来越失去竞争力了吗

题记&#xff1a; java真的在越来越失去竞争力了吗&#xff1f;最近参加校招面试&#xff0c;过程中有问道java的问题&#xff0c;有的同学很直接了当&#xff08;或者是不假思索&#xff09;地说&#xff0c;java已经过时了吧&#xff0c;现在学java的人越来越少了。那么事实…...

【通过zip方式安装mysql服务】

通过zip方式安装mysql服务 Mysql安装包下载mysql安装及环境配置1.解压缩配置环境变量初始化mysql配置安装mysql服务启动MySQL服务连接mysql修改root用户密码 Mysql安装包下载 通过访问mysql官网下载&#xff1a;mysql下载地址 mysql安装及环境配置 1.解压缩 下载完成后&am…...

每日OJ题_WY3小易的升级之路_数学模拟_C++_Java

目录 牛客_WY3小易的升级之路_数学模拟 题目解析 C代码 Java代码 牛客_WY3小易的升级之路_数学模拟 小易的升级之路_牛客题霸_牛客网 (nowcoder.com) 描述&#xff1a; 小易经常沉迷于网络游戏.有一次,他在玩一个打怪升级的游戏,他的角色的初始能力值为 a.在接下来的一段…...

python xml的读取和写入

import xml.etree.ElementTree as ET from xml.dom import minidom# 读取XML文档 tree ET.parse("./xml_3/z_20240827_001.xml") root tree.getroot() # 获取size元素 size_find_0 root.find("size") # 获取width子元素 size_w size_find_0.find("…...

WebGL 小白入门学习

1. WebGL是什么&#xff1f; WebGL&#xff08;Web Graphics Library&#xff09;是一种JavaScript API&#xff0c;它允许你在不需要安装任何额外插件的情况下&#xff0c;直接在浏览器中渲染高性能的2D和3D图形。WebGL利用了用户的图形处理单元&#xff08;GPU&#xff09;来…...

OSI七层协议

OSI&#xff08;Open System Interconnection&#xff09;七层协议&#xff0c;即开放式系统互联参考模型&#xff0c;是一个由国际标准化组织&#xff08;ISO&#xff09;提出的用于描述计算机网络中通信的结构和功能的理论模型。它将网络通信过程分为七个层次&#xff0c;每个…...

超平面(Hyperplane)和半空间(Halfspace)

文章目录 一、超平面&#xff08;Hyperplane&#xff09;1. 定义2. 超平面的方程3. 例子4. 超平面的性质 二、半空间&#xff08;Halfspace&#xff09;1. 定义2. 半空间的表示3. 半空间的性质 三、超平面与半空间的关系四、应用1. 线性规划2. 机器学习3. 计算几何4. 凸分析 五…...

TCP(Transmission Control Protocol,传输控制协议)整理

TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的传输协议&#xff0c;它是OSI&#xff08;Open System Interconnection&#xff0c;开放式系统互联&#xff09;模型中的第四层协议&#xff0c;通常使用于网络中的…...

R语言绘制线性回归图

线性回归图以二维坐标系展示两个变量关系。数据点代表实际观测值&#xff0c;核心是线性回归线。此线通过统计方法确定&#xff0c;与数据点距离平方和最小。它反映变量间线性趋势&#xff0c;斜率正负决定相关方向。可用于预测因变量值&#xff0c;也能进行推断统计。在数据分…...

C++进阶:map和set的使用

目录 一.序列式容器和关联式容器 二.set系列的使用 2.1set容器的介绍 2.2set的构造和迭代器 2.3set的增删查 2.4insert和迭代器遍历的样例 2.5find和erase的样例 ​编辑 2.6multiset和set的差异 2.7简单用set解决两道题 两个数组的交集 环形链表二 三.map系列的使用…...

深入理解C++ STL中的 vector

文章目录 1. vector 的概述1.1 vector 是什么&#xff1f;1.2 vector 的优点1.3 vector 的缺点 2. vector 的基本使用2.1 vector 的定义2.2 基本操作2.3 示例2.4 迭代器的使用 3. vector 的内部实现原理3.1 动态数组的实现3.2 内存管理3.3 内存扩展策略3.4 元素的插入与删除3.4…...

MySQL 安装与配置详细教程

MySQL 安装与配置详细教程 MySQL 是一款流行的关系型数据库管理系统&#xff0c;广泛应用于 Web 应用和应用程序中。在本文中&#xff0c;我们将提供一份详细的 MySQL 安装与配置教程&#xff0c;帮助初学者快速上手。 ## 1. 安装 MySQL 首先&#xff0c;我们需要从 MySQL 官…...

理解智能合约:区块链在Web3中的运作机制

随着区块链技术的不断发展&#xff0c;“智能合约”这一概念变得越来越重要。智能合约是区块链应用的核心之一&#xff0c;正在推动Web3的发展&#xff0c;为数字世界带来了前所未有的自动化和信任机制。本文将深入探讨智能合约的基本原理、运作机制&#xff0c;以及它在Web3生…...

QT工程概述

在Qt中&#xff0c;创建 "MainWindow" 与 "Widget" 项目的主要区别在于他们的用途和功能范围&#xff1a; MainWindow&#xff1a;这是一个包含完整菜单栏、工具栏和状态栏的主窗口应用程序框架。它适合于更复 杂的应用程序&#xff0c;需要这些额外的用户…...

redis安装 | 远程连接

1.redis的安装 在Ubuntu下安装redis【网址】使用root账号使用apt来安装。使用apt安装比较的方便&#xff0c;但是安装的版本可能就不是最新的版本。 $ su root $ apt list --installed | grep redis # 查看是否安装 $ apt search redis # 查看apt中的redis版本 $ apt install…...