Redis的过期删除策略和内存淘汰策略

news2025/4/25 6:59:47

🤔

  • 过期删除和内存淘汰乍一看很像,都是做删除操作的,这么分有什么意思?

  • 首先,设置过期时间我们很熟悉,过期时间到了,我么的键就会被删除掉,这就是我们常认识的过期删除,但是实际上的过期删除真的是这样吗?

1 过期删除策略

实际上,一般过期之后的键不是立刻删除的,一般过期键的清除策略有三种,分别是定时删除定期删除惰性删除

1.1 定时删除

定时删除时在设置键的过期时间的同时,创建一个定时器,让定时器在键过期时间来临时,立即执行对键的删除操作

定时删除看起来和我们原来想象的一样,这样对内存来说也确实比较友好,但是对CPU不友好,如果某个时间段比较多的key过期的话,可能会影响命令处理性能。

1.2 惰性删除

所谓惰性就是不要那么勤快,随时都盯着,用的时候发现不对再去删就行了,具体就是使用的时候发现key过期了,此时再进行删除。这个策略的思路是对应用而言,只要不访问,过不过期对于业务而言都无所谓,但是这样也是有代价的,就是,如果某些key一直不来访问,那么本该过期的key,就变成常驻的key了,这种策略对CPU友好,对内存不友好

1.3 定期删除

定期删除就是每隔一段时间,程序就对数据库进行一次检查,每次删除一部分过期键。

定时删除实际实现起来非常不容易,主要如果出现了一场,可能会有key遗漏,以及如果程序重启,原来的定时器就随之重启消失了,那就需要在启动时对过期的键进行进行一些操作,可能是重建定时器,这些都是额外的工作,而且会引入多余的复杂度。

从实际的功能而言,其实并不需要那么实时,所以惰性删除是可以考虑的,但是出于应删尽删的考虑,要保证最终没有漏网之鱼,那有没有这样的策略呢?

有的有的,兄弟有的,加上定期删除作为兜底就可以了。所以Redis过期键采用的删除策略是惰性删除+定期删除二者结合的方式进行,这样就可以以一定CPU消耗换取对内存的友好

1.3.1 定期删除需要关注的两个问题:

  1. 定期删除的频率

    1. 这取决于Redis周期任务的执行频率,周期任务里面会做关闭客户端,删除过期key的一系列任务,可以用INFO查看周期任务频率

  2. 每次删除的数量

    1. 随机选取20个key判断是否过期,同时检查过期key数量占比,如果>25%,则再抽20个重复上述流程,这里是一个循环的过程。

    2. Redis为了保证定期删除不会出现循环过度导致线程卡死现象,为此增加了定期删除循环流程的时间上限,默认不过超过25ms。

前面我们说到,过期删除和内存淘汰的区别是什么,都是做删除操作的?

我们先看它们解决的问题分别是什么?过期删除策略解决的是:过期的key怎么删除?内存淘汰策略解决的是:内存满了怎么办?

由此我们就可以推断出,它们在触发条件目标上,存在区别。

过期删除策略内存淘汰策略
触发条件键的过期时间到达(TTL到期)内存使用达到 maxmemory 限制
目标清理明确声明不再需要的数据腾出内存空间以维持服务可用性

2 内存淘汰策略

🤔 我们刚说到,内存淘汰策略是解决内存满了怎么办?Redis可以存多少数据?什么时候算满?

  • 在32位操作系统中,使用maxmemory来设置最大运行内存,默认值是3G,因为32位的机器最大只支持4GB的内存,而系统本身就需要一定的内存资源来支持运行,默认3G相对合理。

  • 在64位操作系统中,maxmemory的默认值是0,表示没有内存大小限制,也可以主动配置maxmemory

  • 当Redis存储超过这个配置值,则触发内存淘汰,所以说,内存满了其实就是达到设置的maxmemory值了

2.1 有哪些内存淘汰策略?

2.1.1 不进行数据淘汰的策略

noeviction(Redis3.0之后,默认的内存淘汰策略):它表示当运行内存超过最大设置内存时,不淘汰任何数据,这时如果有新的数据写入,会报错通知禁止写入,不淘汰任何数据但是如果没用数据写入的话,只是单纯的查询或者删除操作的话,还是可以正常工作。

2.1.2 进行数据淘汰的策略

2.1.2.1 在设置了过期时间的数据中进行淘汰
  1. volatile-random:随机淘汰设置了过期时间的任意键值

  2. volatile-ttl:优先淘汰更早过期的键值

  3. volatile-lru(Redis3.0之前,默认的内存淘汰策略):淘汰所有设置了过期时间的键值中,最久未使用的键值

  4. volatile-lfu(Redis4.0后新增的内存淘汰策略):淘汰了所有设置过期时间的键值中,最少使用的键值。

2.1.2.2 在所有数据范围内进行淘汰
  • allkeys-random:随机淘汰任意键值

  • allkeys-lru:淘汰整个键值中最久未使用的键值

  • allkeys-lfu(Redis4.0后新增的内存淘汰策略):淘汰整个键值中最少使用的键值

2.1.3 内存淘汰算法LRU

🤔 什么是LRU算法?

LRU全称是Least Recently Used,翻译为最近最少使用,会选择淘汰最近最少使用的数据。

传统LRU算法的实现是基于“链表”结构,链表中的元素按照操作顺序从前往后排列,最新操作的键会被移动到表头,当需要内存淘汰时,只需要删除链表尾部的元素即可,因为链表尾部的元素就代表最久未被使用的元素

Redis并没有使用这样的方式实现LRU算法,因为传统的LRU算法存在两个问题:

  • 需要用链表管理所有的缓存数据,这会带来额外的空间开销

  • 当用数据被访问时,需要在链表上把该数据移动到头端,如果有大量数据被访问,就会带来很多链表移动操作,会很耗时,进而会降低Redis缓存性能

Redis是如何实现LRU算法的?

  • Redis实现的是一种近似LRU算法,目的是为了更好的节约内存,它的实现方式是在Redis的对象结构体中添加一个额外的字段lru,用于记录此数据的最后一次访问时间

  • 当Redis进行内存淘汰时,会使用随机采样的方式来淘汰数据,它是随机取5个值(这个值可以进行配置),然后淘汰最久没有使用的哪个

  • Redis实现LRU算法的优点:

    • 不用为所有的数据维护一个大链表,节约了空间占用

    • 不用在每次数据访问时都移动链表项,提升了缓存的性能

  • 但是LRU算法有一个问题:无法解决缓存污染问题:

    • 当应用一次性加载大量仅访问一次的数据时:

      • 这些数据的“最后一次访问时间”非常新,会挤占缓存空间

      • 即使他们是“一次性”的,LRU也会认为它们“最近被使用过”,而淘汰真正有价值但最后一次访问较早的热点数据

      • 即短期批量操作干扰长期热点数据的保留

就像你学习了一天,刚刚打开手机看了一眼,你的家长回家,说,怎么就知道玩手机,不学习

补充:Redis的对象结构体

Redis中的key和value都被封装成redisObject结构体,key的类型只能是字符串类型,而value的类型可以是任意的Redis数据类型。

typedef struct redisObject {
    unsigned type:4;          // 对象类型(如字符串、哈希等)
    unsigned encoding:4;     // 对象编码(底层实现方式)
    unsigned lru:LRU_BITS;   // LRU时间戳 或 LFU计数器(内存淘汰策略相关)24bit
    int refcount;            // 引用计数器(内存回收)
    void *ptr;               // 指向实际数据的指针
} robj;

🤔 如何解决缓存污染的问题呢?

Redis4.0之后引入了LFU算法来解决这个问题。

2.1.4 内存淘汰算法LFU

LFU全称是Least Frequently Used翻译为最近最不常用,LFU是根据数据访问次数来淘汰数据的,它的核心思想是“如果数据过去被访问多次,那么将来被访问的频率也更高”。

所以LFU算法会记录每个数据的访问次数。当一个数据被再次访问时,就会增加该数据的访问次数。这样就解决了偶尔被访问一次之后,数据留存在缓存中很长一段时间的问题

Redis是如何实现LFU算法的?

  • LFU算法相比于LRU算法的实现,多记录了数据的访问频次的信息。

  • LRU和LFU并不会同时开启,基于这个情况,加上节约内存的考虑,Redis在LFU策略下复用lru字段,用它来表示LFU的信息

  • 将24bits的lru字段分成两段来存储,高16bit存储ldt(Last Decrement Time),低8bit存储logc(Logitstic Counter)

    • ldt是用来记录key的访问时间戳

    • logc是用来记录key的访问频次,它的值越小表示使用的频率越低,越容易淘汰,每个新加入的key的logc初始值为5

    • 注:logc并不是单纯的访问次数,而是访问频次(访问频率),因为logc会随时间推移而衰减。

      • 如果上一次访问时间很久,那么访问频次就会衰减,比如一个key,它原来的logc是255,夸张一点,一年没访问了,不该衰减吗

Redis访问key时,logc的变化:

  1. 先按照上次访问距离当前时长,来对logc进行衰减

  2. 然后,再按照一定概率增加logc的值

redis.conf提供了两个配置项,用于调整LFU算法从而控制logc的增长和衰减:

  • lfu-decay-time用于调整logc的衰减速度,它是一个以分钟为单位的数值,默认值为1,lfu-decay-time值越大,衰减越慢

  • lfu-log-factor用于调整logc的增长速度,lfu-log-factor值越大,logc增长越慢

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2342215.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL:数据库设计

目录 一、范式 二、第一范式 二、第二范式 三、第三范式 四、设计 (1)一对一关系 (2)一对多关系 (3)多对多关系 一、范式 数据库的范式是一种规则(规范),如果我们…

synchronized关键字的实现

Java对象结构 synchronized锁升级过程 为了优化synchronized锁的效率,在JDK6中,HotSpot虚拟机开发团队提出了锁升级的概念,包括偏向锁、轻量级锁、重量级锁等,锁升级指的就是“无锁 --> 偏向锁 --> 轻量级锁 --> 重量级…

opencv 图像的旋转

图像的旋转 1 单点旋转2. 图片旋转(cv2.getRotationMatrix2D)3. 插值方法3.1 最近邻插值(cv2.INTER_NEAREST)3.2 双线性插值(cv2.INTER_LINEAR)3.3 像素区域插值(cv2.INTER_AREA)3.4 双三次插值(cv2.INTER_CUBIC&#…

【多线程】线程互斥 互斥量操作 守卫锁 重入与线程安全

文章目录 Ⅰ. 线程互斥概念Ⅱ. 互斥锁的概念Ⅲ. 互斥锁的接口一、互斥锁的定义二、初始化互斥锁三、销毁互斥锁四、互斥量的加锁和解锁① 加锁接口② 解锁接口五、改进买票系统💥注意事项Ⅳ. 互斥锁的实现原理一、问题引入二、复习知识三、实现原理Ⅴ. 封装锁对象 &&…

空闲列表:回收和再利用

空闲列表:回收和再利用 手动与自动内存管理 手动管理:程序员需要明确地分配和释放内存。自动管理:例如使用垃圾收集器(GC),它能够自动检测并回收未使用的对象,不需要程序员干预。 对于某些数据结构如B树,…

计算机组成与体系结构:直接内存映射(Direct Memory Mapping)

目录 CPU地址怎么找到真实的数据? 内存映射的基本单位和结构 1. Pages(页)——虚拟地址空间的基本单位 2. Frames(页框)——物理内存空间的基本单位 3. Blocks(块)——主存和缓存之间的数据…

STM32提高篇: 蓝牙通讯

STM32提高篇: 蓝牙通讯 一.蓝牙通讯介绍1.蓝牙技术类型 二.蓝牙协议栈1.蓝牙芯片架构2.BLE低功耗蓝牙协议栈框架 三.ESP32-C3中的蓝牙功能1.广播2.扫描3.通讯 四.发送和接收 一.蓝牙通讯介绍 蓝牙,是一种利用低功率无线电,支持设备短距离通信的无线电技…

SpringMVC处理请求映射路径和接收参数

目录 springmvc处理请求映射路径 案例:访问 OrderController类的pirntUser方法报错:java.lang.IllegalStateException:映射不明确 核心错误信息 springmvc接收参数 一 ,常见的字符串和数字类型的参数接收方式 1.1 请求路径的…

【程序员 NLP 入门】词嵌入 - 上下文中的窗口大小是什么意思? (★小白必会版★)

🌟 嗨,你好,我是 青松 ! 🌈 希望用我的经验,让“程序猿”的AI学习之路走的更容易些,若我的经验能为你前行的道路增添一丝轻松,我将倍感荣幸!共勉~ 【程序员 NLP 入门】词…

从物理到预测:数据驱动的深度学习的结构化探索及AI推理

在当今科学探索的时代,理解的前沿不再仅仅存在于我们书写的方程式中,也存在于我们收集的数据和构建的模型中。在物理学和机器学习的交汇处,一个快速发展的领域正在兴起,它不仅观察宇宙,更是在学习宇宙。 AI推理 我们…

大模型AI的“双刃剑“:数据安全与可靠性挑战与破局之道

在数字经济蓬勃发展的浪潮中,数据要素已然成为驱动经济社会创新发展的核心引擎。从智能制造到智慧城市,从电子商务到金融科技,数据要素的深度融合与广泛应用,正以前所未有的力量重塑着产业格局与经济形态。 然而,随着…

操作系统概述与安装

主流操作系统概述 信创平台概述 虚拟机软件介绍与安装 windows server 安装 centos7 安装 银河麒麟V10 安装 一:主流服务器操作系统 (1)Windows Server 发展历程: 1993年推出第一代 WindowsNT(企业级内核&am…

开发了一个b站视频音频提取器

B站资源提取器-说明书 一、功能说明 本程序可自动解密并提取B站客户端缓存的视频资源,支持以下功能: - 自动识别视频缓存目录 - 将加密的.m4s音频文件转换为标准MP3格式 - 将加密的.m4s视频文件转换为标准MP4格式(合并音视频流)…

基于javaweb的SpringBoot校园服务平台系统设计与实现(源码+文档+部署讲解)

技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…

PHYBench:首个大规模物理场景下的复杂推理能力评估基准

2025-04-23, 由北京大学物理学院和人工智能研究所等机构共同创建的 PHYBench 数据集,这是一个专门用于评估大型语言模型在物理场景下的复杂推理能力的高质量基准。该数据集包含 500 道精心策划的物理问题,覆盖力学、电磁学、热力学、光学、现代物理和高级…

Red:1靶场环境部署及其渗透测试笔记(Vulnhub )

环境介绍: 靶机下载: https://download.vulnhub.com/red/Red.ova 本次实验的环境需要用到VirtualBox(桥接网卡),VMware(桥接网卡)两台虚拟机(网段都在192.168.152.0/24&#xff0…

深入详解人工智能数学基础——概率论中的KL散度在变分自编码器中的应用

🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C++, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C++、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle,mysql,postgresql等进行开发应用…

测试模版x

本篇技术博文摘要 🌟 引言 📘 在这个变幻莫测、快速发展的技术时代,与时俱进是每个IT工程师的必修课。我是盛透侧视攻城狮,一名什么都会一丢丢的网络安全工程师,也是众多技术社区的活跃成员以及多家大厂官方认可人员&a…

Openharmony 和 HarmonyOS 区别?

文章目录 OpenHarmony 与 HarmonyOS 的区别:开源生态与商业发行版的定位差异一、定义与定位二、技术架构对比1. OpenHarmony2. HarmonyOS 三、应用场景差异四、开发主体与生态支持五、关键区别总结六、如何选择?未来展望 OpenHarmony 与 HarmonyOS 的区别…

uniapp 仿小红书轮播图效果

通过对小红书的轮播图分析&#xff0c;可得出以下总结&#xff1a; 1.单张图片时容器根据图片像素定高 2.多图时轮播图容器高度以首图为锚点 3.比首图长则固高左右留白 4.比首图短则固宽上下留白 代码如下&#xff1a; <template><view> <!--轮播--><s…