【LRU】一文让你弄清 Redis LRU 页面置换算法

news2025/4/7 7:42:54

Q:一天同事问,我放在 redis 中的 key,为什么有时候过一段时间数据就没有了,我并没有设置过期时间呀??😳😳

A:你的 redis 淘汰策略是什么样的,这个 key 可能是被 redis 自身的淘汰策略干掉了

一看 redis 的 config 文件 redis.conf

果然,你配置的是 maxmemory_policy allkey-lfu ,这个是 Redis 中的淘汰策略,是会从 redis 数据集中挑选使用频率最低的数据进行淘汰的

Q:不明觉厉,摸摸头👀👀

A:我给你简单说一下关于 redis 的淘汰策略吧

首先,redis 删除数据的策略目前来看有三种

  • 👀定时删除

见名知意,定时,自然就像我们定起床闹钟一样,此处是定一个删除 key 的闹钟,当我们对一个 key 设置过期时间的时候,会同时开启一个定时器,当时间到到的时候,就会删除这个 key

这种方式,需要我们额外开一个定时器,会消耗 CPU 资源

  • 👀惰性删除

惰性,一看就知道这种删除方式是被动的,若一个 key 过期了,redis 不会主动去删除他,而是当这个 key 再次被访问的时候,redis 看他有没有失效,若失效,则删除他

这种方式可以看出,如果一些过期的 key ,再没有被再次访问之前,就会一直存在内存中,非常浪费内存资源

  • 😁主动删除

顾名思义,这种方式是 redis 中会去设置各种策略,去按照不同的策略去删除一些不符合要求的数据,简单的,我们来看看 Redis 的淘汰策略,掌握主动权

Redis 的淘汰策略

可以看出 redis 的淘汰策略大体上有 5 种方式

  • LRU
  • LFU
  • RANDOM

会从数据集中随机选择数据进行删除,按照配置的策略不同 allkeys-random 则是将在所有数据集中进行随机 , volatile-random 是在已经设置了过期时间的数据中去随机淘汰

  • TTL

会从设置了过期时间的数据中,挑选要过期的数据进行淘汰

  • No-eviction (默认,不驱逐数据)

上述五种,看了后面三种都比较好理解,对于前面两种,我来详细给你说一下他的原理,便于你能够理解和记住,而不是去背诵他,面试的时候还可以手撸一下实现代码

前面两种方式,LRU 和 LFU 都是属于页面置换算法,其中还有一个最简单的页面置换算法是 FIFO,学过基本数据结构的对于 FIFO 先入先出的特性并不模式,因此就不在这里展开了,咱们本次主要聊聊 LRU ,很多时候很多同学还是不理解

LRU 的思想和实现

LRU 全称为:Least recently used

含义为:最近最少使用

思想是:如果数据最近被访问过,那么未来最近一段时间,这个数据未来被访问的几率也会更大

思想就是这么简单,不过他已经足够指导我们实践了

我们根据思想来分析一下 LRU 如何去实现它

首先,我们知道数据在内存中是用链表的方式来连接,此处我们可以使用双向链表

那么,对于链表来说,插入数据是很方便的,但是读取的数据的话,难道我们每一次都要去遍历一遍 key 吗?

自然不是,因此对于 LRU 中,还是用 hashmap 来存放 key 和链表上具体数据节点的关系

这样,当访问任何一个 key 的时候,就可以通过 hashmap 中取到节点,进而取到节点的值即可,这种方式的时间复杂度就可以从 O (n) 降低到 O(1)

那么对于去实现 最近最少使用 的思想,那就是结合 hashmap 和双向链表来进行实现

  • 插入数据使用头插法,若访问到链表中的某个数据,则将该数据移动到链表头
  • 若插入数据时,链表容量已满,此时淘汰链表尾部的数据

✔举例时刻

举个例子,相信你就可以明白

例如,我们要插入这些数据 set(0,0),set(1,1),set(2,2),set(3,3),set(4,4),get(3) ,链表的容量为 3,来模拟一下 LRU 的处理过程

先插入 3 个数据到 链表中 0, 1, 2,

此处为了简单,咱们将 key 和 value 的值做成一样的

插入 3,

链表容量已满,删除链表尾的数据,这个时候,就已经是发生了缺页,需要对数据进行置换,淘汰链表尾,hashmap 中删除链表为对应的数据,新增 3 这个节点的数据到 hashmap 中

插入4,

链表容量已满,删除链表尾的数据,这个时候,就已经是发生了缺页,需要对数据进行置换,淘汰链表尾,hashmap 中删除链表为对应的数据,新增 4 这个节点的数据到 hashmap 中

获取 3,

由于链表中已经有 3 ,因此会将 3 移动到链表头

从上述演示中,我们可以看到关于 LRU 的关键逻辑

  1. 实现基本的链表
  1. 插入的数据时,如果链表已满,那么链表尾部的数据直接删掉,即淘汰
  1. 查询数据的时候,若数据已经存在于链表中,则将该节点移动到头节点上

那么在实现的时候,只需要实现基本的链表以及其对应的基础方法 (头插法,尾插法,移动节点,查询节点等) ,以及使用 hashmap 来记录链表中具体的 key 和具体的节点

思想,以及 LRU 中链表数据变动的过程明白了,写代码都是很简单的事情,感兴趣的 xdm 可以查看我的 code 地址:https://github.com/qingconglaixueit/my_lru_lfu/blob/main/my_lru/lru.go

实现结果

链接中的代码,可以看到 main.go 实现如下

咱们可以将数据修改成文中的例子,

运行 main.go 之后,可以看到结果如下:

红色部分,表示发生了缺页中断, 向链表中追加的 key 是 0,1,2,3,4,3

感兴趣的话,还是将 代码下载下来,自己跑一下,多多感受一下 LRU 的思想和流程,很容易就可以理解😁😁

总结

这下对于 Redis 的淘汰策略,心中有个数了吧

对于 LRU的具体实现方式相信你可以可以很容易的看明白的,实践起来吧,源码地址为:https://github.com/qingconglaixueit/my_lru_lfu

感谢阅读,欢迎交流,点个赞,关注一波 再走吧

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~

文中提到的技术点,感兴趣的可以查看这些文章:

  • 什么是单点登录?什么又是 OAuth2.0?
  • 什么是分布式锁?他解决了什么样的问题?
  • 【Redis 系列】redis 存储结构原理 1
  • 【Redis 系列】redis 存储结构原理 2
  • 我是如何用 redis 分布式锁来解决线上历史业务问题的

可以进入地址进行体验和学习:https://xxetb.xet.tech/s/3lucCI

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

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

相关文章

dirname - return directory part of PATH.

用Visual Studio 2022开发Linux程序, 用ssh连接 函数单元测试 下载glibc解压到E:\library\GNU\glibc-2.38 mzhDESKTOP-GITL67P:~$ sudo /etc/init.d/ssh start * Starting OpenBSD Secure Shell server sshd …

【Spring】-Bean的作用域和生命周期

作者:学Java的冬瓜 博客主页:☀冬瓜的主页🌙 专栏:【Framework】 主要内容:Lombok的使用,Bean作用域的分类和修改。Singleton、Prototype。spring的执行流程,Bean的生命历程。 文章目录 一、Bea…

树莓派+墨水屏 = DIY一个超慢速电影播放器

安装电子墨水屏这里使用了 Waveshare 的一款墨水屏,带驱动板。将驱动板插入树莓派的 GPIO 即完成屏幕和树莓派的连接。驱动这个屏幕需要启用树莓派的 SPI 接口。运行 sudo raspi-config 进入配置工具来启用 SPI 运行python例程 安装函数库 sudo apt-get update su…

指针笔试题详解

个人主页:点我进入主页 专栏分类:C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 欢迎大家点赞,评论,收藏。 一起努力,一起奔赴大厂。 目录 1.前言 2.指针题写出下列程序的结…

Unity Windows上Inspector界面黑屏无法显示

问题描述:在Windows上Unity 打开工程Inspector显示黑色,不可用。如下图: 可能的问题。 Unity 设置Windows上默认渲染方式显卡不支持。 解决方案: 一、换一个好一点显卡 二、如下图:

Transformer的上下文学习能力

《Uncovering mesa-optimization algorithms in Transformers》 论文链接:https://arxiv.org/abs/2309.05858 为什么 transformer 性能这么好?它给众多大语言模型带来的上下文学习 (In-Context Learning) 能力是从何而来?在人工智能领域里&…

实验室安全教育与考试

目录 我的错题(2个)新知识题目(10个)刚开始不太理解的题目(10个)写在最后(免责声明) 我的错题(2个) 18.发生电气火灾时可以使用的灭火设备包括:&…

SAP Service服务重注册技术手册

当SAP服务被卸载后,或SAP虚拟机整机copy后(可能还需要涉及主机名更改),需要对SAP服务重注册。 在路径 \sapmnt\<SID>\ DVEBMGS00\exe下使用程序sapstartsrv.exe来卸载、安装SAP服务: 其中<SID>、NR参考Service中需要卸载的服务名(卸载后,Services列表中的SA…

【UE 粒子练习】08——LOD概述

目录 概念 应用举例 一、检查当前粒子系统中是否设置了LOD 二、添加LOD 三、LOD设置&#xff08;单个粒子发射器&#xff09; 四、LOD设置&#xff08;多个粒子发射器&#xff09; 概念 在 Unreal Engine 中&#xff0c;LOD&#xff08;Level of Detail&#xff0c;细…

Kubernetes 学习总结(37)—— Kubernetes 之 CoreDNS 企业级应用

前言 IP 地址会有变更&#xff0c;程序配置IP地址&#xff0c;所有涉及到此IP的地方都需要改变&#xff0c;对运维和研发都不友好。IP不容易被记住。引入域名来替换 IP&#xff0c;这样业务使用唯一标识域名&#xff0c;域名可以通过 DNS 服务器解析成 IP 供业务三层通信使用。…

时间复杂度、空间复杂度

一、时间复杂度 1、概念 时间复杂度&#xff1a;计算的是当一个问题量级增加的时间&#xff0c;时间增长的趋势&#xff1b; O&#xff08;大O表示法&#xff09;&#xff1a;渐进的时间复杂度 2、举例 ① 以下 for 循环的时间复杂度&#xff1a;O(1 3n) O(n) 去掉常数…

rom修改----安卓系列机型如何内置app 如何选择so文件内置

系统内置app的需求 在与各工作室对接中操作单中&#xff0c;很多需要内置客户特定的有些app到系统里&#xff0c;这样方便客户刷入固件后直接调用。例如内置apk 去开机引导 去usb调试 默认开启usb安全设置等等。那么很多app内置有不同的反应。有的可以直接内置。有的需要加so…

(十三)VBA常用基础知识:编程时各种常用操作之设值,取值,活动窗口设定

cell里设置内容的两个写法 Sub test() Range("A1").Value "帅哥" Cells(1, 2).Value "帅哥 too" End Sub2.cell里内容的取得 Sub test() Range("A1").Value "帅哥" Cells(1, 2).Value "帅哥 too" a Range(…

Baumer工业相机堡盟工业相机如何通过BGAPI SDK设置相机的图像剪切(ROI)功能(C#)

Baumer工业相机堡盟工业相机如何通过BGAPI SDK设置相机的图像剪切&#xff08;ROI&#xff09;功能&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机的图像剪切&#xff08;ROI&#xff09;功能的技术背景CameraExplorer如何使用图像剪切&#xff08;ROI&#xff09;功…

[nodejs]NVM使用指南

安装 官网链接 使用 # 版本号 nvm version# 显示node是运行在32位还是64位。 nvm arch# 显示已安装的列表 nvm list nvm ls# 使用制定版本node。可指定32/64位 nvm use [version] [arch]# 显示可安装的所有版本 nvm list available# 安装最新版本 nvm install latest# 安装指…

【Linux】系统编程简单线程池(C++)

目录 【1】线程池概念 【1.1】线程池 【1.2】线程池的应用场景 【1.3】线程池的种类 【1.4】线程池示例 【2】线程池代码 【1】线程池概念 【1.1】线程池 一种线程使用模式。线程过多会带来调度开销&#xff0c;进而影响缓存局部性和整体性能。而线程池维护着多个线程&a…

【新书推荐】用户画像:了解用户,助力企业成长 ——《用户画像:平台构建与业务实践》

文章目录 〇、引子一、什么是用户画像二、用户画像的优势三、如何实现用户画像四、用户画像应用中的问题五、总结新书推荐 —— 《用户画像&#xff1a;平台构建与业务实践》内容简介目录 〇、引子 在当今市场竞争激烈的时代&#xff0c;了解用户需求、提高用户体验已成为企业…

WebGL 雾化

目录 前言 如何实现雾化 线性雾化公式 雾化因子关系图 根据雾化因子计算片元颜色公式 示例程序&#xff08;Fog.js&#xff09; 代码详解​编辑 详解如何计算雾化因子&#xff08;clamp()&#xff09; 详解如何计算最终片元颜色&#xff08;根据雾化因子计算片元颜色…

二、搭建Java环境

搭建Java环境 搭建Java环境1.1.下载JDK1.2.在Win10下配置JDK环境 —————————————————————————————————————————————————— ———————————————————————————————————————————————…

李航老师《统计学习方法》第1章阅读笔记

1.1 统计学习 统计学习的特点 统计学习&#xff1a;计算机基于数据构建概率统计模型并运用模型对数据进行预测与分析 现在人们提及机器学习时&#xff0c;往往指统计机器学习&#xff0c;所以可以认为本书介绍的是机器学习方法 统计学习的对象 统计学习研究的对象是数据(data)…