Redis 服务等过期策略和内存淘汰策略解析

news2024/11/19 23:40:31

redis服务是基于内存运行的,所以很多数据都存放在内存中,但是内存又不是无限的,所以redis就引出了key的过期和淘汰策略。

一、Redis的过期策略:

我们在set key的时候,可以给它设置一个过期时间,比如expire key 60。指定这key在60s后过期,60s后那redis是如何处理的嘛?

我们先来介绍几种过期策略:

1、定时过期:

每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即对key进行清除。

优点:该策略可以立即清除过期的数据,对内存很友好;

缺点:但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。

2、惰性过期:

只有当访问一个key时,才会判断该key是否已过期,过期则清除。

优点:该策略可以最大化地节省CPU资源;

缺点:却对内存非常不友好。

注:极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。

3、定期过期:

每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。

该策略是前两者的一个折中方案。

通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。
expires字典会保存所有设置了过期时间的key的过期时间数据,其中,key是指向键空间中的某个键的指针,value是该键的毫秒精度的UNIX时间戳表示的过期时间。

键空间是指该Redis集群中保存的所有键。

4、惰性过期和定期过期结合使用:

假设Redis当前存放30万个key,并且都设置了过期时间,如果你每隔100ms就去检查这全部的key,CPU负载会特别高,最后可能会挂掉。
因此,redis采取的是定期过期,每隔100ms就随机抽取一定数量的key来检查和删除的。
但是呢,最后可能会有很多已经过期的key没被删除。这时候,redis采用惰性删除。在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间并且已经过期了,此时就会删除。
但是呀,如果定期删除漏掉了很多过期的key,然后也没走惰性删除。就会有很多过期key积在内存内存,直接会导致内存爆的。或者有些时候,业务量大起来了,redis的key被大量使用,内存直接不够了,Redis用8(2^3)种内存淘汰策略保护自己~ 

二、Redis 内存淘汰策略:

1、volatile-lru:

当内存不足以容纳新写入数据时,从设置了过期时间的key中使用LRU(最近最少使用)算法进行淘汰;

2、allkeys-lru:

当内存不足以容纳新写入数据时,从所有key中使用LRU(最近最少使用)算法进行淘汰。

3、volatile-lfu:

4.0版本新增的策略,当内存不足以容纳新写入数据时,在过期的key中,使用LFU(最不经常使用)算法进行删除key。

4、allkeys-lfu:

4.0版本新增,当内存不足以容纳新写入数据时,从所有key中使用LFU(最不经常使用)算法进行淘汰;

5、volatile-random:

当内存不足以容纳新写入数据时,从设置了过期时间的key中,随机淘汰数据;

6、allkeys-random:

当内存不足以容纳新写入数据时,从所有key中随机淘汰数据。

7、volatile-ttl:

当内存不足以容纳新写入数据时,在设置了过期时间的key中,根据过期时间进行淘汰,越早过期的优先被淘汰;

8、noeviction:

默认策略,当内存不足以容纳新写入数据时,新写入操作会报错。

三、 LRU算法与LFU算法:

Redis 在 4.0 版本之前的缓存淘汰算法,只支持 random 和 LRU。random 太简单粗暴了,可能把热点数据给淘汰掉,一般不会使用。

LRU比 random 好一点,会优先淘汰最久没被访问的数据,但是它也有一个缺点,就是无法真正表示数据的冷热程度。

1、什么是LRU算法:

LRU是一种基于时间的内存淘汰策略(最近最少使用,会淘汰掉长时间不使用的数据)。它假设最近被访问的数据在未来也更有可能被访问,而较长时间未被访问的数据更可能不再被使用。根据这个策略,LRU算法会淘汰最久未被访问的数据,以腾出内存空间。

LRU算法示意图:

流程解析: 

  1. 向一个缓存空间依次插入三个数据A/B/C,填满了缓存空间;
  2. 读取数据A一次,按照访问时间排序,数据A被移动到缓存头部;
  3. 插入数据D的时候,由于缓存空间已满,触发了LRU的淘汰策略,数据B被移出,缓存空间只保留了D/A/C。

2、如何实现LRU算法:

LRU算法比较核心的思想是要记录最近被访问的、最早被访问的数据,在访问数据和修改数据(编辑、新增、删除)数据时,该部分数据就会变成最新的数据,内存不够时会把最早被访问的数据删除掉。

​ 很快我们锁定了List,最近被访问的数据(最新的数据) 可以存在在List的第一个位置,最早被访问的(最老的数据)可以存放在List的最后一个位置。

但是由于数据的访问、数据的修改都会导致数据位置的变动,所以使用List会存在一定的性能问题,因此我们可以采用一个双向链表来暂时解决该问题,可以采用一个双向链表维护缓存的上一次使用时间,并且可以使数据插入/删除等操作的时间复杂度是O(1)。

此外当链表(linkedlist)越来越长时,我们访问某个元素时需要遍历访问,性能较差,因此新增一个哈希表(hashtable),记录链表节点的映射关系,解决如果只使用双向链表每次判断key是否存在时都需要遍历整个链表的问题。

3、什么是LFU算法:

LFU是一种基于访问频率的内存淘汰策略(最不经常使用,会淘汰掉使用次数最少的数据)。它假设经常被访问的数据在未来仍然频繁被访问,而较少被访问的数据更可能不再被使用。根据这个策略,LFU算法会淘汰访问频率最低的数据,以释放内存空间。

4、如何实现LFU算法:

实现LFU算法的一种常见方法是使用三个数据结构:

哈希表(keyToValue):用于存储键值对,提供快速的键值查找功能。
哈希表(keyToFreq):用于存储键的访问频率,记录每个键被访问的次数。
哈希表(freqToKeys):用于存储相同访问频率的键的集合,以便快速获取具有相同访问频率的键。

LFU算法的实现步骤如下:

(1)、初始化缓存容量、最小访问频率为0以及上述三个哈希表。

(2)、当需要获取缓存中的数据项时,首先检查键是否存在于keyToValue哈希表中。如果不存在,则返回-1表示未找到;如果存在,则获取对应的值,并更新该键的访问频率。

(3)、当需要插入新的数据项时,首先检查缓存是否已满。如果已满,则根据LFU原则淘汰一个访问频率最低的数据项。然后将新的键值对添加到keyToValue哈希表中,并将访问频率设置为1,并将键添加到对应访问频率的键集合中。如果缓存未满,则直接将新的键值对添加到keyToValue哈希表中,并将访问频率设置为1,并将键添加到对应访问频率的键集合中。

(4)、当更新键的访问频率时,首先从原访问频率的键集合中移除该键。如果原访问频率的键集合为空且等于最小访问频率,则更新最小访问频率。然后将键添加到新访问频率的键集合中,并更新键的访问频率。

(5)、当需要淘汰数据项时,从最小访问频率的键集合中选择一个键进行淘汰,并从keyToValue、keyToFreq和freqToKeys哈希表中移除该键。

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

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

相关文章

【UnityRPG游戏制作】RPG项目的背包系统商城系统和BOSS大界面

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:Uni…

【06】JAVASE-数组讲解【从零开始学JAVA】

Java零基础系列课程-JavaSE基础篇 Lecture:波哥 Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机,Java 仍是企业和开发人员的首选开发平台。…

华为MRS服务使用记录

背景:公司的业务需求是使用华为的这一套成品来进行开发,使用中发现,这个产品跟原生的Hadoop的那一套的使用,还是有很大的区别的,现记录一下,避免以后忘了 一、原始代码的下载 下载地址:MRS样例…

使用Umbrello学习工厂模式

工厂方法模式之所以有一个别名叫多态性工厂模式是因为具体工厂类都有共同的接口, 或者有共同的抽象父类。 当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体对象以及一个具体工厂对 象,原有工厂对象不需要进行任何修改,也不…

Go语言中有哪些常见的编码规范和最佳实践?

文章目录 一、命名规范1. 包名2. 变量名3. 函数名原因 二、代码格式1. 花括号位置2. 缩进3. 空格示例代码原因 三、错误处理1. 检查错误2. 错误值3. 多重错误处理示例代码原因 四、注释1. 注释内容2. 注释位置3. 避免冗余注释示例代码原因 五、总结 在Go语言编程中,…

数据结构––复杂度

目录 一.时间复杂度 1.1定义 1.2时间复杂度的分类 1.3时间复杂度基本计算规则 1.4例子 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.4.10 1.4.11 1.4.12 1.4.13 二.空间复杂度 2.1定义 2.2推导大O阶方法 一.时间复杂度 1.1定义 算法的时间…

面试算法题精讲:最长公共子序列

面试算法题精讲:最长公共子序列 题面 题目来源:1143. 最长公共子序列 题目描述: 给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列(LCS)的长度。如果不存在公共子序列 ,返回…

浅谈大数据时代下的电商风控||电商数据API接口

抢抢抢!最后1天,双十一直播活动来啦!抢直播专属优惠…… 视频号 随着大数据时代的兴起,互联网电商风控已经从无风控、人工抽取规则为主的简易规则模型发展到当前基于大数据的风控。与金融风控不同,互联网电商风控呈现出…

vue3 ——笔记 (条件渲染,列表渲染,事件处理)

条件渲染 v-if v-if 指令用于条件性地渲染一块内容,只有v-if的表达式返回值为真才会渲染 v-else v-else 为 v-if 添加一个 else 区块 v-else 必须在v-if或v-else-if后 v-else-if v-else-if 是v-if 的区块 可以连续多次重复使用 v-show 按条件显示元素 v-sh…

[Java]线程生命周期与线程通信

【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://blog.csdn.net/m0_69908381/article/details/138101131 出自【进步*于辰的博客】 线程生命周期与进程有诸多相似,所以我们很容易将…

【Vue】可拖拽排序表格组件的实现与数据保存

1、描述 使用el-table-draggable组件来创建一个可拖拽的表格。 表格中的数据存储在tableData数组中,每个对象都有sortOrder、id、name和age属性。 当用户拖拽表格行并释放时,handleRowOnEnd方法会被调用, 更新tableData中每个对象的sortO…

super与this

目录 原型链与继承继承中的原型链 classsuper与this 我们可能会对一个问题感到好奇:为什么在派生类中,我们需要在调用this之前调用super。我们通常将其视为一种规范,却很少深入探究这个规范的真正意义。许多人认为super不过是ES6之前继承方式…

vercel.app 部署的服务国内无法最优解决方案

今天在部署 waline 评论系统时,发现国内 IP 无法访问,这将导致评论系统无法使用,由于我的站点是技术站点需要和用户评论沟通,但是如果评论无法使用的话就会导致流失更多的用户,通过自己实际测试后发现一个最优的解决方…

【IR 论文】DPR — 最早提出使用嵌入向量来检索文档的模型

论文:Dense Passage Retrieval for Open-Domain Question Answering ⭐⭐⭐⭐⭐ EMNLP 2020, Facebook Research Code: github.com/facebookresearch/DPR 文章目录 一、论文速读二、DPR 的训练2.1 正样本和负样本的选取2.2 In-batch negatives 技巧 三、实验3.1 数据…

编写一个函数fun,它的功能是:实现两个字符串的连接(不使用库函数strcat),即把p2所指的字符串连接到p1所指的字符串后。

本文收录于专栏:算法之翼 https://blog.csdn.net/weixin_52908342/category_10943144.html 订阅后本专栏全部文章可见。 本文含有题目的题干、解题思路、解题思路、解题代码、代码解析。本文分别包含C语言、C++、Java、Python四种语言的解法完整代码和详细的解析。 题干 编写…

长度最小的子数组 ---- 滑动窗口

题目链接 题目: 分析: 解法一:暴力解法, 找到所有连续子数组, 保留满足条件的解法二: 利用滑动窗口 找子数组 因为数组中都是正整数, 通过进窗口的操作, 我们找到一组, 如示例一中的2,3,1,2, 判断满足和>7, 那么根据单调性, 我们就不再需要判断加上后面两个数的两个子数组…

在 GitHub 中掌握键盘快捷键的简短指南

你是否知道 GitHub 几乎每页都有键盘快捷键?这篇文章将带你探索 GitHub 的键盘快捷键世界,以及它们如何帮助你快速导航和执行操作。 读完这篇,你将能够: 掌握快捷键:想知道如何访问这些快捷键?在任何 Git…

记录浏览器打开网站拦截提示不安全解决方法

浏览器可能会因为多种原因显示“不安全”的警告,这通常是由于安全设置不当或配置错误造成的。以下是一些常见的原因和解决方法: 1. HTTPS未启用 原因:如果网站使用HTTP而不是HTTPS,浏览器可能会显示不安全的警告。 解决方法:配置SSL/TLS证书并使用HTTPS来加密数据传输…

64、二分-搜索二维矩阵

思路: 通过使用二分方式,对于每行进行二分,因为每行的最后一个数小于下一行的第一个数,我们就可以依次二分。首先取出行数N,然后从0-N进行二分,如果mid最后一个数小于目标值说明0-mid中没有,舍弃…

开源博客项目Blog .NET Core源码学习(19:App.Hosting项目结构分析-7)

本文学习并分析App.Hosting项目中后台管理页面的主页面。如下图所示,开源博客项目的后台主页面采用layui预设类layui-icon-shrink-right设置样式,点击主页面中的菜单,其它页面采用弹框或者子页面形式显示在主页面的内容区域。   后台主页面…