Redis中的过期删除与内存淘汰

1.Redis中的过期删除策略

        在 Redis 中,过期删除策略是为了管理存储在 Redis 中的带有过期时间的数据。每当数据存储时,可能会为其设定一个过期时间。当到达这个时间点后,该数据就被标记为“过期”。为了确保不再需要的过期数据不会占用系统资源,Redis 会通过过期删除策略来移除它们。

1. 1惰性删除策略

什么是惰性删除策略?

        惰性删除策略的意思是,Redis 不会主动去检查所有键是否过期,而是等到用户访问一个键时才去检查它是否已经过期。如果 Redis 在访问这个键时发现它已经过期了,就会立即删除这个键,并返回一个“键不存在”的结果。

        通俗地说,惰性删除策略就像是“按需检查”。就好比在图书馆里,管理员不会逐一检查每本书是否过期,而是等到有人去借某本书时,才去检查这本书的借阅期限。只有发现过期了,管理员才会收回这本书。

惰性删除的优缺点:

  • 优点:惰性删除不占用额外资源来检查键的状态,节省了系统性能。
  • 缺点:如果某些键长期无人访问,那么即便它们过期了也不会被删除,依然会占用内存。

1.2 定期删除策略

什么是定期删除策略?

        定期删除策略是一种 Redis 主动定期检查键是否过期的方式。Redis 会每隔一段时间(比如默认每秒)抽样检查一些带有过期时间的键。如果发现某些键已经过期,它会立即删除这些键。注意,这种检查并不是遍历所有键,而是从带有过期时间的键中随机抽样一部分来检查。

        通俗地说,定期删除策略就像是“定期抽查”。假设图书管理员每隔一段时间,随便检查一部分书籍,看看它们的借阅期限是否过期。如果发现某本书过期了,管理员就把它收回。这样可以减少无用的过期数据。

定期删除的优缺点:

  • 优点:相比惰性删除策略,它能及时清除一部分无用的过期数据,避免内存占用过多。
  • 缺点:定期删除策略无法保证每次都能检查到所有过期数据,因此依然会有一些过期但未被清除的数据留在内存中。此外,如果检查频率太高,也会影响系统性能。

2.Redis 持久化中过期键的策略

        当 Redis 数据持久化到硬盘上时,有可能会遇到一些带有过期时间的数据。这时,Redis 如何处理这些过期键,取决于你使用的是哪种持久化格式。我们从 RDB 持久化格式AOF 持久化格式 两方面分别讲解。

2.1 RDB 文件

2.1.1 RDB 文件生成阶段

        当 Redis 触发 RDB 文件生成时,会将内存中的数据快照写入到 RDB 文件。在生成 RDB 文件时,Redis 会对键的过期时间进行检查,确保只把有效的、未过期的数据写入文件。因此,如果一个键已经过期,Redis 会直接跳过这个键,不会将它写入 RDB 文件。这种处理方式避免了过期键被保存到持久化文件中,节省了存储空间。

  • 例子:假设键 "session:12345" 已经过期,那么在 RDB 文件生成时,Redis 检查到它已经过期,会将该键从快照中剔除,不写入 RDB 文件。

  • 优缺点

    • 优点:RDB 文件不会保存过期的数据,文件体积更小,且避免了加载过期数据的情况。
    • 缺点:RDB 文件生成过程稍微增加了检查过期时间的开销。

2.2.2  RDB 文件加载阶段

        当 Redis 重启并加载 RDB 文件时,主服务器和从服务器会有不同的过期键处理逻辑:

  • 主服务器:在主服务器上加载 RDB 文件时,会对每个键进行过期检查,如果发现某个键已经过期了,Redis 会直接跳过,不将其加载到内存中。这样可以确保主服务器只加载有效的数据。

  • 从服务器:在从服务器加载 RDB 文件时,Redis 不会进行过期检查。即使某些键在从服务器看来已过期,它们依旧会被加载到内存中。这个处理方式是为了让从服务器的数据状态与主服务器保持一致。在主服务器上,过期键删除的操作会同步到从服务器,确保最终数据的一致性。

  • 例子:假设 RDB 文件包含一个键 "user

    ",它的过期时间是今天中午。如果在今天下午重启主服务器,主服务器会检测到这个键已过期,直接跳过加载它。而从服务器则会无条件加载该键,并等待从主服务器同步删除指令。
  • 优缺点

    • 优点:主服务器能够自动清理过期键,避免加载到内存中;从服务器则确保与主服务器的状态一致。
    • 缺点:从服务器加载过期键可能会消耗内存,直到主服务器的同步删除命令生效。

2.2 AOF 文件

2.2.1 AOF 文件写入阶段

        在 Redis 处理 AOF 持久化时,每次执行写操作,Redis 会把命令追加到 AOF 文件中。对于有过期时间的键,当它过期并被删除时,Redis 会在 AOF 文件中追加一条 DEL 命令。这条命令标记了该键的删除,确保 AOF 文件反映当前的内存状态。

  • 例子:假设 Redis 在某次访问中发现键 "session:456" 已经过期并执行删除操作,那么 Redis 会将 DEL session:456 命令追加到 AOF 文件中。下次重启时,AOF 文件会根据这条命令删除过期键。

  • 优缺点

    • 优点:AOF 文件可以及时反映键的过期状态,重启后保证只加载有效数据。
    • 缺点:AOF 文件会随着每次操作变大,但可通过重写机制优化。

2.2.2 AOF 文件重写阶段

        为了避免 AOF 文件过大,Redis 提供了 AOF 文件重写机制。重写时,Redis 会基于当前内存数据生成一个新的 AOF 文件。对于已经过期的数据,不会将它们写入新的 AOF 文件。这样,新生成的 AOF 文件就只包含当前有效的数据,不会带有任何过期数据。

  • 例子:假设键 "cache

    " 在内存中已经过期,则在 AOF 文件重写时,Redis 会忽略该键,不会将它写入新的 AOF 文件。
  • 优缺点

    • 优点:重写后的 AOF 文件更加精简,没有过期数据,占用的磁盘空间较小。
    • 缺点:重写过程中会占用一些系统资源,不过能够大幅减少 AOF 文件体积。

3.Redis 主从模式中过期键的处理

        在 Redis 的主从复制结构下,主库和从库的过期机制是这样分配的:

  1. 主库(Master):主库会定期检查和删除已过期的键,通过主动过期扫描和惰性过期检查来清理过期数据。主库删除一个键时,会在 AOF 文件或复制流中加入一条 DEL 指令,并同步给从库。这意味着从库会接收到这条 DEL 指令,从而清除相应的过期键。

  2. 从库(Slave):从库不会进行主动的过期扫描,也不主动检查过期键的状态。它只是被动地接收来自主库的 DEL 指令,并删除相应的键。这种被动删除的机制确保了主从库在键的状态上始终保持一致。

  3. 被动删除的触发:当从库响应客户端的读请求时,如果请求到的是一个过期键(此键在从库上未被主动删除),从库并不会直接删除它,而是仍然返回数据。因为主从复制的核心目标是保持数据的一致性,而非数据的新鲜度;从库的数据主要用于高效地进行读操作,而不是清理过期键。

        总结来说,从库依赖于主库的过期删除通知来清理过期键,从而减少过期检查带来的资源消耗,并最大限度地保证主从数据一致。

4.Redis的内存淘汰机制

4.1Redis 的八种内存淘汰策略

  1. noeviction:不淘汰任何键。当内存满了之后,写操作会返回错误,不允许新增数据。

  2. volatile-random:只从设置了过期时间的键中随机淘汰一个键,以释放内存。

  3. volatile-ttl:只从设置了过期时间的键中淘汰生存时间(TTL)最短的键。即选择即将到期的键进行淘汰。

  4. volatile-lru:只从设置了过期时间的键中淘汰最近最少使用的键(LRU 策略)。

  5. volatile-lfu:只从设置了过期时间的键中淘汰最少使用的键(LFU 策略)。

  6. allkeys-random:从所有键中随机淘汰一个键,不论是否设置了过期时间。

  7. allkeys-lru:从所有键中淘汰最近最少使用的键(LRU 策略),不论是否设置了过期时间。

  8. allkeys-lfu:从所有键中淘汰最少使用的键(LFU 策略),不论是否设置了过期时间。

4.2 LRU 和 LFU 算法的区别

  • LRU(Least Recently Used):即最近最少使用,关注的是数据的“最近访问时间”。如果数据很久没有被访问过,系统认为它的再利用可能性较低,因此优先被淘汰。换句话说,越久没被访问的键,越容易被淘汰

  • LFU(Least Frequently Used):即最少使用,关注的是数据的“访问频率”。如果一个键的访问频率很低,则系统认为它的重要性较低,可以优先淘汰。因此,那些被访问次数少的数据更容易被淘汰

总结

  • LRU 适合短期内访问频率波动较大的数据,因为它仅考虑“最近访问”。
  • LFU 适合较长期、访问次数较为稳定的情况,因为它累计访问频率,而不是按时间优先。

4.3 什么是 LRU 算法?

LRU 算法的全称是“最近最少使用”算法。LRU 的基本理念是:

  • 如果一个键最近被访问过,那么未来也更可能被访问。这种情况适用于很多缓存场景,因为短期访问有一定的连贯性。
  • 反之,那些长时间没有被访问的数据很可能未来也不再需要,因此更适合被淘汰。

常见 LRU 实现方式

  • 一般可以通过链表来实现 LRU,将最近访问的节点移到表头,而长时间未访问的节点逐渐移向表尾,最终从表尾淘汰。

4.4 Redis 是如何实现 LRU 算法的?

        Redis 的 LRU 实现并不严格,因为 Redis 强调高性能和轻量操作,严格实现 LRU 会消耗大量内存和时间,因此 Redis 采用了一种近似 LRU的方式:

  1. 访问时间记录:每个键在 Redis 中都记录了最近一次访问的时间戳信息,这是一个 24 位的访问计数器,用来帮助 Redis 判断哪些键最近未被使用。这个计数器会在键被访问时更新。

  2. 采样淘汰

    • 当 Redis 达到内存上限时,它不会遍历所有键去找到最久未使用的键,而是采用随机采样的方式:从键空间中随机抽取一部分键(默认 16 个),然后从中找到最近最少访问的键进行淘汰。
    • 这种“采样”方法可以避免在键数量较大时遍历带来的性能开销,但仍然实现类似 LRU 的效果。
  3. 可调采样数量:Redis 提供了 maxmemory-samples 参数来控制采样的键数量。例如,maxmemory-samples 的默认值是 5,即每次淘汰会随机抽取 5 个键,并从中选取最久未使用的键进行淘汰。采样数量越大,结果越接近严格 LRU,但会增加系统开销。

4.5 什么是 LFU 算法?

        LFU 算法的全称是“最少使用”算法,核心思想是:

  • 如果一个数据使用频率很低,那么它在未来再次使用的可能性较低,因此可以优先淘汰。
  • 换句话说,历史访问频率低的数据,更适合被淘汰。适合访问次数稳定的场景。

        与 LRU 不同,LFU 关注的是数据的访问频率而非最近访问时间。LFU 更适合一些被长期且稳定访问的数据场景。

4.6 Redis 是如何实现 LFU 算法的?

Redis 中的 LFU 实现也采取了近似算法,并采用了“频率计数+衰减”的机制,具体分为以下几个要点:

  1. 访问频率计数器

    • 每个键在 Redis 中都有一个 8 位计数器,用于记录该键的访问频率,范围为 0 到 255。
    • Redis 并不会严格增加访问频率计数,而是采用概率增量。当键被访问时,计数器以一定概率递增,这样能防止访问频率高的键增长速度过快,避免少量高频数据长期占据空间,减少“垄断”现象。
  2. 衰减机制

    • LFU 中,访问频率会随着时间逐渐“遗忘”历史访问次数,避免“僵尸数据”问题(即过去访问频繁但长时间未被访问的键)。
    • Redis 设置了衰减机制,计数器会随时间按比例减少。这种逐渐减少的设计可以逐步将那些曾经高频但已长时间不被访问的数据淘汰出去。
    • Redis 会定期对这些计数值进行衰减,通常是在达到内存上限或频繁触发淘汰时进行衰减操作,从而避免低频访问的数据长期占据内存。

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

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

相关文章

机器学习——贝叶斯

🌺历史文章列表🌺 机器学习——损失函数、代价函数、KL散度机器学习——特征工程、正则化、强化学习机器学习——常见算法汇总机器学习——感知机、MLP、SVM机器学习——KNN机器学习——贝叶斯机器学习——决策树机器学习——随机森林、Bagging、Boostin…

403 Request Entity Too Lager(请求体太大啦)

昨天收到 QA 的生产报障,说是测试环境的附件上传功能报了 403 的错误,错误信息:403 Request Entity Too Lager。我尝试复现问题,发现传个几兆的文件都费劲啊,一传一个失败。不用说,项目用到 ng 代理&#x…

232转485模块测试

概述 常用的PLC一般会有两个左右的232口,以及两个左右的485口,CAN口等,但是PLC一般控制的设备可能会有很多,会超出通讯口的数量,此时我们一般会采用一个口接多个设备,这种情况下要注意干扰等因素&#xff0…

科技资讯|Matter 1.4 标准正式发布,低功耗蓝牙助力其发展

连接标准联盟(CSA)宣布推出最新的 Matter 1.4 版本,引入了一系列新的设备类型和功能增强,有望提高包括 HomeKit 在内的智能家居生态系统之间的互操作性。 设备供应商和平台能够依靠增强的多管理员功能改善多生态系统下的用户体验&…

SpringBoot实现文件上传并返回url链接

检查依赖 确保pom.xml包含了Spring Boot Web的依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>创建Controller 创建公用上传文件控制器 package…

FPGA学习笔记#7 Vitis HLS 数组优化和函数优化

本笔记使用的Vitis HLS版本为2022.2&#xff0c;在windows11下运行&#xff0c;仿真part为xcku15p_CIV-ffva1156-2LV-e&#xff0c;主要根据教程&#xff1a;跟Xilinx SAE 学HLS系列视频讲座-高亚军进行学习 学习笔记&#xff1a;《FPGA学习笔记》索引 FPGA学习笔记#1 HLS简介及…

苍穹外卖05-Redis相关知识点

目录 什么是Redis&#xff1f; redis中的一些常用指令 value的5种常用数据类型 各种数据类型的特点 Redis中数据操作的常用命令 字符串类型常用命令&#xff1a; 哈希类型常用命令 列表操作命令 集合操作命令 有序集合操作命令 通用命令 在java中操作Redis 环境…

SpringBoot(八)使用AES库对字符串进行加密解密

博客的文章详情页面传递参数是使用AES加密过得,如下图所示: 这个AES加密是通用的加密方式,使用同一套算法,前端和后端都可以对加密之后的字符串进行加密解密操作。 目前线上正在使用的是前端javascript进行加密操作,将加密之后的字符串再传递到后端,PHP再进行解密操作。…

【Windows erver】配置高性能电源管理

操作场景 在 Windows Server 操作系统上&#xff0c;需要配置高性能电源管理&#xff0c;才能支持实例软关机&#xff0c;否则云服务器控制台只能通过硬关机的方式关闭实例。本文档以 Windows Server 2012 操作系统为例&#xff0c;介绍配置电源管理的方法。 操作说明 修改电…

【JAVA基础】MAVEN的安装及idea的引用说明

本篇文章主要讲解&#xff0c;maven的安装及集成在idea中进行构建项目的详细操作教程。 日期&#xff1a;2024年11月11日 作者&#xff1a;任聪聪 所需材料&#xff1a; 1、idea 2024版本及以上 2、maven 3.9.9安装包 3、一个空java springBoot项目&#xff0c;可以使用阿里云…

AI变现,做数字游民

在数字化时代&#xff0c;AI技术的迅猛发展不仅改变了各行各业的生产方式&#xff0c;还为普通人提供了前所未有的变现机会。本文将探讨如何利用AI技术实现变现&#xff0c;成为一名数字游民&#xff0c;享受自由职业带来的便利与乐趣。 一、AI技术的变现潜力 AI技术以其强大…

解非线性方程

实验类型&#xff1a;●验证性实验 ○综合性实验 ○设计性实验 实验目的&#xff1a;进一步熟练掌握解非线性方程的二分法算法、牛顿迭代法&#xff0c;提高编程能力和解算非线性方程问题的实践技能。 实验内容&#xff1a;用二分法算法(取[a,b][1,2])、牛顿迭代法解算非线性…

详细分析Guava库中的注解@VisibleForTesting,用于标记提醒私有(附Demo)

目录 前言1. 基本知识2. Demo 前言 对于Java基本知识推荐阅读&#xff1a; java框架 零基础从入门到精通的学习路线 附开源项目面经等&#xff08;超全&#xff09;【Java项目】实战CRUD的功能整理&#xff08;持续更新&#xff09; 从实战中学习&#xff1a; 源码如下&…

Hadoop(YARN)

文章目录 YARN基础架构YARN工作原理YARN调度器和调度算法先进先出调度器容量调度器公平调度器 YARN常用命令 YARN基础架构 YARN是Hadoop集群的资源管理和调度系统&#xff0c;它负责为各种分布式计算任务分配和管理资源,包含以下组件&#xff1a;ResourceManager&#xff0c;N…

【GoWeb示例】通过示例学习 Go 的 Web 编程

文章目录 你好世界HTTP 服务器路由&#xff08;使用 gorilla/mux&#xff09;连接到 MySQL 数据库MySQL 数据库简单操作模板静态资源和文件操作表单处理中间件&#xff08;基础&#xff09;中间件&#xff08;高级&#xff09;会话JSONWebsockets密码哈希 你好世界 Go语言创建…

【C语言】Union

一.Union的用法 1.什么是Union? union 共用体名{ 成员列表 }; union&#xff0c;“联合体、共用体”&#xff0c;在某种程度上类似结构体struct的一种数据结构&#xff0c;共用体(union)和结构体(struct)同样可以包含很多种数据类型和变量。 2.为什么使用union&#xff1…

2024最新版JavaScript逆向爬虫教程-------基础篇之Chrome开发者工具学习

目录 一、打开Chrome DevTools的三种方式二、Elements元素面板三、Console控制台面板四、Sources面板五、Network面板六、Application面板七、逆向调试技巧7.1 善用搜索7.2 查看请求调用堆栈7.3 XHR 请求断点7.4 Console 插桩7.5 堆内存函数调用7.6 复制Console面板输出 工欲善…

大数据学习12之HBase

1.基本概念 1.1简介 Apache HBase&#xff08;Hadoop DataBase&#xff09;是一个开源的、高可靠性、高性能、面向列&#xff08;这里指列族&#xff0c;非列式存储&#xff09;、可伸缩、实时读写的分布式数据库&#xff0c;其设计思想来源于 Google 的 BigTable 论文。利用 …

(Go基础)Go的运行流程步骤与包的概念

1. 快速入门 所有的go开发&#xff0c;都必须存在并包含在某一个包内 .go 是go语言程序的后缀名 1.1 编译 通过使用 go build 命令对该go文件进行编译&#xff0c;生成.exe文件 1.2 运行 运行刚刚生成出来的test.exe文件既可&#xff0c;不过并不不是双击&#xff0c;而是在…

CSS教程(八)- 盒子模型

1、介绍 核心内容 盒子模型、浮动和定位&#xff0c;帮助我们实现页面布局 本质&#xff1a;页面布局过程 准备好相关的页面元素&#xff0c;网页元素基本都是盒子 Box 利用 CSS 设置盒子的样式&#xff0c;摆放到相应的位置 向盒子中填充相应内容 网页布局的核心本质&…