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

Redis的内存淘汰策略分析

概念

  • LRU 是按访问时间排序,发生淘汰的时候,把访问时间最久的淘汰掉。
  • LFU 是按频次排序,一个数据被访问过,把它的频次 + 1,发生淘汰的时候,把频次低的淘汰掉。

几种LRU策略

以下集中LRU测率网上有很多,我自己结合项目加以整理。也可以选择跳过。

1. 普通LRU

在这里插入图片描述

  1. 一般使用双向链表+map实现,新数据加入链表表头
  2. 每当缓存命中时,将数据移动到表头
  3. 链表长度超过设定值,将尾部数据淘汰
    缺点:当热点数据较多时,随后来了一次偶发性的操作,操作的数据较多,容易将热点数据淘汰出去。

2. LRU-K

考虑到传统LRU的缺点,改进措施是记录数据的被访问次数。维护两个LRU队列,一个数据访问次数队列,一个缓存队列。当访问达到预设值K时,加入到缓存队列中。对于偶然性的访问非热点数据时,命中次数不够,不会加入到缓存队列中,则不会挤出热点数据。
在这里插入图片描述

  1. 命中数据后,加入访问次数队列中,被访问次数+1,同普通LRU的逻辑。
  2. 淘汰数据。
  3. 当访问次数超过预设值,从此队列中移除,加入到缓存队列中,按照访问时间排序。
  4. 缓存队列中的数据再次被命中,按照访问时间顺序排序。
  5. 淘汰数据。
    缺点:需要谨慎考虑K值的设定,设定过大会导致数据很难被淘汰。整体内存消耗也偏高。同时也要按照访问时间重排序。

3. 2Queue

优化重排序问题。
在这里插入图片描述

  1. 数据被访问后,加入到FIFO队列中。
  2. FIFO按照访问时间进行淘汰。
  3. 当数据再次被访问时,则移到LRU队列头部。
  4. 数据再次被访问,移动到头部。
  5. LRU队列淘汰。

4. Multi Queue

同2Queue,增加了多个FIFO队列,按照预设条件,从左到右逐级提升等级。随着数据被淘汰,从右向左逐级降级。
在这里插入图片描述

Redis的LRU/LFU策略

内存淘汰策略配置

  • maxmemory: 指定限制内存大小。默认=0,表示无限制。
  • maxmemory_policy: 指定的淘汰策略,目前有以下几种:
    • noeviction: 默认值,不处理。
    • allkeys-lru:对所有的key都采取LRU淘汰策略。
    • volatile-lru:仅对设置了过期时间的key采取LRU淘汰。
    • allkeys-random: 随机回收key。
    • Volatile-random: 随机回收设置了过期时间的key。
    • volatile-ttl:仅淘汰设置了过期时间的key,并淘汰生存时间更小的key。
    • Volatile-lfu: 对设置了过期时间的key采取LFU策略。
    • Allkeys-lfu: 对全部key采取LFU策略
  • maxmemory_samples: 随机采样精度。官方表示配10更接近真实的LRU策略。

2. Redis的LRU策略

  • 给每个key记录一个lru time。
  • 每次访问key的时候,更新key的lru time。
  • 按照策略配置。在一定范围内,找访问时间最早的key,将其淘汰。
  • 具体看下面的源码分析。

3. Redis的LRU策略的缺陷

//从左到右是时间轴,每个波浪线代表一个时间单位
//竖线是当前时间点~~~~~A~~~~~A~~~~~A~~~~A~~~~~A~~~~~A~~|
~~B~~B~~B~~B~~B~~B~~B~~B~~B~~B~~B~~B~|
~~~~~~~~~~C~~~~~~~~~C~~~~~~~~~C~~~~~~|
~~~~~D~~~~~~~~~~D~~~~~~~~~D~~~~~~~~~D|//可以看到,如果4个key中非要淘汰一个,肉眼看出来一定是淘汰D,因为它访问的次数最少。但是由于
//当前时间点,D再次被访问,它的LRU时间又被更新了,导致D不会被淘汰,范围淘汰了C。
//这种情况就不合理,因此redis4.0版本后引入了LFU策略。

4. Redis的LFU策略

struct redisObject {unsigned type:4;unsigned encoding:4;//对于lru而言,这里记录了lru time//对于lfu而言,高24位记录LRU time,低8位记录计数器的值(最大可表示255)unsigned lru:LRU_BITS; int refcount;void *ptr;
};
  • 给每个key记录一个计数count。
  • 由于只有8位长度,最多只能表示255,因此采用了一个因子控制count的增长速度。
  • 新的key加入进来,会设置为预设值(LFU_INIT_VAL),以免为0直接被淘汰。
  • 每当这个key被访问时,按照增长逻辑,增长count值。
  • 每当这个key被放入到淘汰候选池内,则会降低count值。

5. 源码分析

当执行命令,命中数据时,更新数据:

//查找缓存数据时,最终都会调用此函数
//如: lookupKeyRead(), lookupKeyWrite() 
robj *lookupKey(redisDb *db, robj *key, int flags) {dictEntry *de = dictFind(db->dict,key->ptr);...robj *val = dictGetVal(de);if (val) { if (不能在执行子任务的时候 && !(flags & LOOKUP_NOTOUCH)){if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {//如果是LFU策略,这里就增长LFU计数updateLFU(val);} else {//如果是LRU策略,这里就更新lru timeval->lru = LRU_CLOCK();}}} else {...}return val;
}

然后在处理指令时,如果发现缓存达到了预设值,会触发内存淘汰策略:

int processCommand(client *c) 
{
...if (server.maxmemory && !isInsideYieldingLongCommand()) {//达到了预设值了,这里开始处理内存淘汰逻辑int out_of_memory = (performEvictions() == EVICT_FAIL);...}...
}
//伪代码
int performEvictions(void)
{if (如果是LRU或者LFU策略或者volatile-ttl策略){while (memFree < memNeedFree) {for (i = 0; i < server.dbnum; i++) {db = server.db+i;dict = (如果淘汰策略是针对allkeys) ? db->dict : db->expires;if (只要dict里有数据) {evictionPoolPopulate(i, dict, db->dict, 淘汰候选池);}}}}else if (如果是两种随机策略){for (i = 0; i < server.dbnum; i++) {//用一个静态变量next_db,这样每次都不会只命中第一个dbj = (++next_db) % server.dbnum;db = server.db + j;dict = (如果淘汰策略是针对allkeys) ? db->dict : db->expires;bestkey = 随机找一个keybreak;}}for (k = 淘汰候选池大小-1; k >= 0; k--) {bestkey = 从候选池里逆序找真实存在的key    }if (bestkey) {最后,在这里回收这个key;memFree += 新释放的内存;}//while执行太久了,break掉if (流逝的时间 > eviction_time_limit_us) {break;}
}

开始处理淘汰策略,并将合适的key放入淘汰候选池内,这个池是已从左到右从小到大排好序的:

void evictionPoolPopulate(int dbid, dict *sampledict, //如果策略是allkey,则是db->dict,//如果是volatile则为db->expiresdict *keydict, //db->dictstruct evictionPoolEntry *pool) //这个是候选池
{//这里开始采样//server.maxmemory_samples是一个预设值,官方建议设置为10count = dictGetSomeKeys(sampledict, samples, server.maxmemory_samples);for (j = 0; j < count; j++) {...if (server.maxmemory_policy & MAXMEMORY_FLAG_LRU) {//因为每次key在被loopupKey的时候,都会更新它自己的lru时间//这个函数:lru当前时间 - 当前这个key的lru时间idle = estimateObjectIdleTime(o);} else if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {//取lfu的计数器的计数,这里是255 - 数值,因为最小访问次数的要被淘汰//注意这里顺带给它减少了LFU计数idle = 255-LFUDecrAndReturn(o);} else if (server.maxmemory_policy == MAXMEMORY_VOLATILE_TTL) {//常量 - validle = ULLONG_MAX - (long)dictGetVal(de);} else {}...}
}

相关文章:

Redis的内存淘汰策略分析

概念 LRU 是按访问时间排序&#xff0c;发生淘汰的时候&#xff0c;把访问时间最久的淘汰掉。LFU 是按频次排序&#xff0c;一个数据被访问过&#xff0c;把它的频次 1&#xff0c;发生淘汰的时候&#xff0c;把频次低的淘汰掉。 几种LRU策略 以下集中LRU测率网上有很多&am…...

git命令之遭遇 ignore罕见问题解决

我先来讲讲背景 我的一些文件在ignore了&#xff0c;不会被提交到远程仓库&#xff0c;这时候我的远程仓库中是没有这几个文件的&#xff0c;这时候我如果使用 git reset 的话这时候除了那几个 ignore 的文件以外都被更新的&#xff0c;但是如果我不需要这几个被 ignore 的文件…...

torch DDP多卡训练教程记录

参考 简明教程看这里 --> pytorch分布式训练 和这篇&#xff1a; [PyTorch]> DDP系列第一篇&#xff1a;入门教程 --》 详细解答了pipeline DDP原理篇 --> DDP系列第二篇&#xff1a;实现原理与源代码解析 --》 主要讲 all_reduce 和 sample 的实现 减少GPU占用看这里…...

Jenkins CICD过程常见异常

1 Status [126] Exception when publishing, exception message [Exec exit status not zero. Status [126] 1.1 报错日志 SSH: EXEC: STDOUT/STDERR from command [/app/***/publish.sh] ... bash: /app/***/publish.sh: Permission denied SSH: EXEC: completed after 200…...

Java11新增特性

前言 在前面的文章中&#xff0c;我们已经介绍了 Java9的新增特性 和 Java10的新增特性 ,下面我们书接上文&#xff0c;来介绍一下Java11的新增特性 版本简介 Java 11 是 Java 平台的最新版本&#xff0c;于2018年9月25日发布。这个版本是自Java 8以来最重要的更新之一&…...

安卓常见设计模式13------过滤器模式(Kotlin版)

W1 是什么&#xff0c;什么是过滤器模式&#xff1f;​ 过滤器模式&#xff08;Filter Pattern&#xff09;是一种常用的结构型设计模式&#xff0c;用于根据特定条件过滤和筛选数据。 2. W2 为什么&#xff0c;为什么需要使用过滤器模式&#xff0c;能给我们编码带来什么好处…...

使用spark进行递归的可行方案

在实际工作中会遇到&#xff0c;最近有需求将产品炸开bom到底层&#xff0c;但是ERP中bom数据在一张表中递归存储的&#xff0c;不循环展开&#xff0c;是无法知道最底层原材料是什么。 在ERP中使用pl/sql甚至sql是可以进行炸BOM的&#xff0c;但是怎么使用spark展开&#xff0…...

Spring -Spring之依赖注入源码解析(下)--实践(流程图)

IOC依赖注入流程图 注入的顺序及优先级&#xff1a;type-->Qualifier-->Primary-->PriOriry-->name...

前端设计模式之【单例模式】

文章目录 前言介绍实现单例模式优缺点&#xff1f;后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;前端设计模式 &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出…...

设备零部件更换ar远程指导系统加强培训效果

随着科技的发展&#xff0c;AR技术已经成为了一种广泛应用的新型技术。AR远程指导系统作为AR技术的一种应用&#xff0c;具有非常广泛的应用前景。 一、应用场景 气象监测AR教学软件适用于多个领域&#xff0c;包括气象、环境、地理等。在教学过程中&#xff0c;软件可以帮助学…...

文本生成高精准3D模型,北京智源AI研究院等出品—3D-GPT

北京智源AI研究院、牛津大学、澳大利亚国立大学联合发布了一项研究—3D-GPT&#xff0c;通过文本问答方式就能创建高精准3D模型。 据悉&#xff0c;3D-GPT使用了大语言模型的多任务推理能力,通过任务调度代理、概念化代理和建模代理三大模块&#xff0c;简化了3D建模的开发流程…...

Netty入门指南之NIO 网络编程

作者简介&#xff1a;☕️大家好&#xff0c;我是Aomsir&#xff0c;一个爱折腾的开发者&#xff01; 个人主页&#xff1a;Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏-CSDN博客 当前专栏&#xff1a;Netty应用专栏_Aomsir的博客-CSDN博客 文章目录 参考文献前言基础扫…...

LeetCode(6)轮转数组【数组/字符串】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 189. 轮转数组 1.题目 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1…...

华为云Ascend310服务器使用

使用华为云服务器 cpu: 16vCPUs Kunpeng 920 内存&#xff1a;16GiB gpu&#xff1a;4* HUAWEI Ascend 310 cann: 20.1.rc1 操作系统&#xff1a;Ubuntu aarch64目的 使用该服务器进行docker镜像编译&#xff0c;测试模型。 已知生产环境&#xff1a;mindx版本为3.0.rc3&a…...

【poi导出excel模板——通过建造者模式+策略模式+函数式接口实现】

poi导出excel模板——通过建造者模式策略模式函数式接口实现 poi导出excel示例优化思路代码实现补充建造者模式策略模式 poi导出excel示例 首先我们现看一下poi如何导出excel&#xff0c;这里举个例子&#xff1a;目前想要导出一个Map<sex,List>信息&#xff0c;sex作为…...

自适应模糊PID控制器在热交换器温度控制中的应用

热交换器是一种常见的热能传递设备&#xff0c;广泛应用于各个工业领域。对热交换器温度进行有效控制具有重要意义&#xff0c;可以提高能源利用效率和产品质量。然而&#xff0c;受到热传导特性和外部环境变化等因素的影响&#xff0c;热交换器温度控制难度较大。本文提出一种…...

【系统救援】 Ubuntu重启失败,报错:UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY

问题定位及处理 查看错误信息&#xff1a;/dev/sda3 contains a file system with errors, check forced. /dev/sda3: Inodes that were part of a corrupted orphan linked list found. /dev/sda3: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY. (i.e., without -a or -p o…...

【数据结构】树与二叉树(八):二叉树的中序遍历(非递归算法NIO)

文章目录 5.2.1 二叉树二叉树性质引理5.1&#xff1a;二叉树中层数为i的结点至多有 2 i 2^i 2i个&#xff0c;其中 i ≥ 0 i \geq 0 i≥0。引理5.2&#xff1a;高度为k的二叉树中至多有 2 k 1 − 1 2^{k1}-1 2k1−1个结点&#xff0c;其中 k ≥ 0 k \geq 0 k≥0。引理5.3&…...

第九章 排序【数据结构】【精致版】

第九章 排序【数据结构】【精致版】 前言版权第九章 排序9.1 概述9.2 插入类排序9.2.1 直接插入排序**1-直接插入排序.c** 9.2.2 折半插入排序**2-折半插入排序.c** 9.2.3 希尔排序 9.3 交换类排序9.3.1冒泡排序**4-冒泡排序.c** 9.3.2 快速排序**5-快速排序.c** 9.4 选择类排…...

基于element-plus定义表格行内编辑配置化

文章目录 前言一、新增table组件二、使用步骤 前言 在 基于element-plus定义表单配置化 基础上&#xff0c;封装个Element-plus的table表格 由于表格不同于form组件&#xff0c;需自定义校验器&#xff0c;以下组件配置了单个校验&#xff0c;及提交统一校验方法&#xff0c;且…...

从灯泡寿命到广告点击率:5个真实业务场景,手把手带你选对统计检验方法

当数据会说话&#xff1a;5个业务场景解锁统计检验的正确打开方式 市场部的Lisa盯着电脑屏幕上的A/B测试报告发愁——新旧页面的转化率差异究竟算不算显著&#xff1f;产品经理Mike正在对比培训前后30名客服的响应时长数据&#xff0c;却不确定该用哪种分析方法。这些场景每天都…...

Dify医疗问答上线前最后72小时:必须完成的4层语义一致性验证(含Jieba+UMLS双引擎比对模板)

第一章&#xff1a;Dify医疗问答上线前最后72小时&#xff1a;必须完成的4层语义一致性验证&#xff08;含JiebaUMLS双引擎比对模板&#xff09;在Dify医疗问答系统正式交付前的72小时内&#xff0c;语义一致性验证是阻断临床术语误释、规避医患沟通风险的核心防线。我们采用四…...

RetinaFace人脸检测模型5分钟快速上手:一键部署与关键点绘制实战

RetinaFace人脸检测模型5分钟快速上手&#xff1a;一键部署与关键点绘制实战 1. 准备工作与环境配置 1.1 镜像环境概览 RetinaFace人脸检测镜像已经预装了完整的运行环境&#xff0c;主要组件包括&#xff1a; Python 3.11PyTorch 2.5.0 CUDA 12.4ModelScope基础库优化后的…...

告别拍脑袋!用Python+MindOpt搞定营销预算分配(附实战代码)

用PythonMindOpt实现营销预算智能分配的实战指南 当市场团队拿着季度预算发愁"钱该往哪儿花"时&#xff0c;数据科学的价值就体现在把决策从"凭感觉"升级为"看数据"。去年双十一前&#xff0c;我们团队接手了一个典型case&#xff1a;某母婴品牌…...

别再手动敲AT指令了!用STM32CubeMX HAL库驱动ESP8266连接OneNET的保姆级教程

STM32CubeMX与HAL库驱动ESP8266连接OneNET的工程化实践 在物联网设备开发中&#xff0c;WiFi模块的集成往往是项目成败的关键节点。传统基于AT指令的手动调试方式不仅效率低下&#xff0c;还容易引入人为错误。本文将展示如何利用STM32CubeMX生成的HAL库代码&#xff0c;构建一…...

VRM Blender插件完整教程:从零开始创建虚拟角色模型

VRM Blender插件完整教程&#xff1a;从零开始创建虚拟角色模型 【免费下载链接】VRM-Addon-for-Blender VRM Importer, Exporter and Utilities for Blender 2.93 to 5.1 项目地址: https://gitcode.com/gh_mirrors/vr/VRM-Addon-for-Blender 如果你正在寻找一款能够轻…...

【2026年最新600套毕设项目分享】微信小程序的校园二手数码交易平台(30113)

有需要的同学&#xff0c;源代码和配套文档领取&#xff0c;加文章最下方的名片哦 一、项目演示 项目演示视频 项目演示视频2 二、资料介绍 完整源代码&#xff08;前后端源代码SQL脚本&#xff09;配套文档&#xff08;LWPPT开题报告/任务书&#xff09;远程调试控屏包运…...

Arduino UNO + PCF8574AT驱动多块LCD屏幕?一个IIC总线挂8个设备的配置指南

Arduino UNO PCF8574AT驱动多块LCD屏幕&#xff1a;IIC总线多设备配置实战 在物联网和智能硬件项目中&#xff0c;多屏显示系统正成为越来越普遍的需求。想象一下这样的场景&#xff1a;一个环境监测站需要同时显示温度、湿度、气压、PM2.5等多项数据&#xff1b;或者一个工业…...

掌握Inter字体:现代排版必备的5个专业技巧终极指南

掌握Inter字体&#xff1a;现代排版必备的5个专业技巧终极指南 【免费下载链接】inter The Inter font family 项目地址: https://gitcode.com/gh_mirrors/in/inter Inter字体作为一款专为数字界面设计的现代无衬线字体系统&#xff0c;以其卓越的可读性和强大的OpenTyp…...

5分钟快速上手FF14动画跳过插件:告别冗长副本动画

5分钟快速上手FF14动画跳过插件&#xff1a;告别冗长副本动画 【免费下载链接】FFXIV_ACT_CutsceneSkip 项目地址: https://gitcode.com/gh_mirrors/ff/FFXIV_ACT_CutsceneSkip 还在为《最终幻想14》副本中冗长的动画而烦恼吗&#xff1f;这款专为CN服务器设计的智能跳…...