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

结合源码分析Redis的内存回收和内存淘汰机制,LRU和LFU是如何进行计算的?

Redis 内存回收

1. 过期 key 处理

Redis 之所以性能强,最主要的原因就是基于内存存储。然而单节点的 Redis 其内存大小不宜过大,会影响持久化或主从同步性能。我们可以通过修改配置文件来设置Redis的最大内存:

当内存使用达到上限时,就无法存储更多数据了。为了解决这个问题,Redis 提供了一些策略实现内存回收,在学习 Redis 缓存的时候我们说过,可以通过 expire 命令给 Redis 的 key 设置 TTL(存活时间),key 的 TTL 到期以后,再次访问 name 返回的是 nil,说明这个 key 已经不存在了,对应的内存也得到释放。从而起到内存回收的目的

Redis 本身是一个典型的 key-value 内存存储数据库,因此所有的 key、value 都保存在之前学习过的 Dict 结构中。不过在其 database 结构体中,有两个 Dict:一个用来记录 key-value;另一个用来记录 key-TTL

Redis 的 DB 结构

Redis是如何知道一个key是否过期呢?

利用两个 Dict 分别记录 key-value 对及 key-ttl

是不是 TTL 到期就立即删除了呢?

  1. 惰性删除:顾明思议并不是在 TTL 到期后就立刻删除,而是在访问一个 key 的时候,检查该 key 的存活时间,如果已经过期才执行删除
  1. 周期删除:顾明思议是通过一个定时任务,周期性的抽样部分过期的 key,然后执行删除,执行周期有两种
    • 初始化时设置定时任务serverCron(),按照 server.hz 的频率来执行过期 key 清理,模式为 SLOW
    • Redis 每个事件循环前都会调用beforeSlepp()函数,执行过期 Key 清理,模式为 Fast

SLOW 模式规则:

  • 执行频率受 server.hz 影响,默认为 10,即每秒执行 10 次,每个执行周期 100ms
  • 执行清理耗时不超过一次执行周期的 25%,默认 slow 模式耗时不超过 25ms
  • 逐个遍历 db,逐个遍历 db 中的 bucket(hash 表的角标),抽取 20 个 key 判断是否过期
  • 如果没达到时间上限(25ms)并且过期 key 比例大于 10%,再进行一次抽样,否则结束

FAST 模式规则(过期 key 比例小于 10% 不执行 ):

  • 执行频率受beforeSleep()调用频率影响,但两次 FAST 模式间隔不低于 2ms
  • 执行清理耗时不超过 1ms
  • 只会采样存在明显过期积压的 DB/Bucket,抽取 20 个 key 判断是否过期如果没达到时间上限(1ms)并且过期 key 比例大于 10%,再进行一次抽样,否则结束

Redis 的 SLOW 和 FAST 两种定期过期删除本质上都是由主线程串行执行的,不会并发执行。即使是不同扫描模式,也只是调度频率不同,删除操作永远是串行的,因此不会出现多个线程同时对同一个 bucket 释放内存,也就自然防止了冲突和数据错误

模式

触发时机

调度点

典型频率

目标

SLOW

serverCron100ms/次

主线程定时

10Hz

全局定期均匀采样

FAST

beforeSleep/压力感知

主线程调度插入

ms 级别

过期压力下快速补刀

RedisKey 的 TTL 记录方式:

  • 在 RedisDB 中通过一个 Dict 记录每个 Key 的 TTL 时间

过期 key 的删除策略:

  • 惰性清理:每次查找 key 时判断是否过期,如果过期则删除
  • 定期清理:定期抽样部分 key,判断是否过期,如果过期则删除

定期清理的两种模式:

  • SLOW 模式执行频率默认为 10,每次不超过 25ms
  • FAST 模式执行频率不固定,但两次间隔不低于 2ms,每次耗时不超过 1ms

2. 内存淘汰策略

内存淘汰:就是当 Redis 内存使用达到设置的上限时,主动挑选部分 key 删除以释放更多内存的流程,Redis 会在处理客户端命令的方法 processCommand() 中尝试做内存淘汰:

淘汰策略

Redis支持 8 种不同策略来选择要删除的 key

  1. noeviction: 不淘汰任何 key,但是内存满时不允许写入新数据,默认就是这种策略
  2. volatile-ttl: 对设置了 TTL 的 key,比较 key 的剩余 TTL 值,TTL 越小越先被淘汰
  3. allkeys-random:对全体 key ,随机进行淘汰,也就是直接从db->dict中随机挑选
  4. volatile-random:对设置了 TTL 的 key ,随机进行淘汰,也就是从db->expires中随机挑选
  5. allkeys-lru: 对全体 key,基于LRU算法进行淘汰
  6. volatile-lru: 对设置了 TTL 的 key,基于LRU算法进行淘汰
  7. allkeys-lfu: 对全体 key,基于LFU算法进行淘汰
  8. volatile-lfu: 对设置了 TTL 的 key,基于LFU算法进行淘汰比较容易混淆的有两个:
    • LRU(Least Recently Used),最少最近使用(最近使用的时间越小越容易被淘汰)。用当前时间减去最后一次访问时间,这个值越大则淘汰优先级越高。
    • LFU(Least Frequently Used),最少频率使用。会统计每个 key 的访问频率,值越小淘汰优先级越高

Redis的数据都会被封装为 RedisObject 结构:

LFU的访问次数之所以叫做逻辑访问次数,是因为并不是每次 key 被访问都计数,而是通过运算:

  • 生成 0~1 之间的随机数 R
  • 计算 (旧次数 * lfu_log_factor + 1),记录为 P,lfu-log-factor默认为 10
  • 如果 R < P ,则计数器 + 1,且最大不超过 255
  • 访问次数会随时间衰减,距离上一次访问时间每隔lfu_decay_time分钟(默认 1),计数器减 1

LFU的逻辑访问次数中,如果一个 key 访问的频率越高,那么他的逻辑访问次数递增的概率将会越低,最多递增到 255;其次LFU的逻辑访问次数,会在距离上一次访问间隔lfu_decay_time分组,进行递减

内存淘汰策略:从源码角度分析内存的淘汰策略流程,首先插入 key 时,发现内存已满,Redis 首先判断是否设置了noeviction策略;如果没有设置,那么将判断淘汰策略中是否从Allkeys中进行淘汰,当策略为Allkeys时将从dict中进行选取,反之从expires中选取。然后进一步判断采用内存策略是Random还是LRU/LFU/TTL?如果是RANDOM那么遍历 DB 之后进行随机淘汰;如果是LRU/LFU/TTL,首先 key 的淘汰将会在eviction_pool中完成。在选取 DB 之后,还是会先随机选取maxmemory-sample个 key,然后才会根据不同的策略去进行判断。eviction-pool中是根据一个值进行升序排序之后,将最大的值进行淘汰。LRU/LFU/TTL这三种淘汰策略,我们不可能给每一种都设置一个排序机制,所以 Redis 巧妙的采用了idleTime进行统一标准的判断。对于TTL而言,idleTime等于maxTTL-TTL减去 TTL 剩余有效期,maxTTL-TTL就是 long 的最大值,如果 key 的有效期越短那么idleTime的值也会越大,也就符合idleTime升序排序并淘汰最大的 key;对于LRU而言,idleTime等于当前时间戳减去 key 的时间戳,key 的最少最近访问时间戳越小,代表 key 很久没有被查询,idleTime的值也会越大;最后LFUidleTime计算是 255-LFU 的计数,如果计数越小,说明这个值就越大

Redis 的内存淘汰机制基于一定的概率进行选择,虽然在一开始的时候,可能会出现不合理的清除,但是随着时间的增加,这个淘汰机制的正确率还是很乐观的

相关文章:

结合源码分析Redis的内存回收和内存淘汰机制,LRU和LFU是如何进行计算的?

Redis 内存回收 1. 过期 key 处理 Redis 之所以性能强&#xff0c;最主要的原因就是基于内存存储。然而单节点的 Redis 其内存大小不宜过大&#xff0c;会影响持久化或主从同步性能。我们可以通过修改配置文件来设置Redis的最大内存&#xff1a; 当内存使用达到上限时&#…...

ESG体系

文字来自腾讯元宝 ESG是什么&#xff1f; ESG体系是一套综合评估企业在环境&#xff08;Environmental&#xff09;、社会&#xff08;Social&#xff09;和治理&#xff08;Governance&#xff09; 三个维度表现的非财务绩效标准&#xff0c;旨在衡量企业可持续发展能力和长期…...

基于 KubeKey 3.1.9,快速部署 K8s 1.33.0 高可用集群

作者&#xff1a;丁鑫磊&#xff0c;云原生运维工程师&#xff0c;专注于 KubeSphere 与 K8s 的深度应用&#xff0c;致力于自动化方向的探索与实践。热衷于挖掘 KubeSphere 的运维潜力&#xff0c;借助其简化 K8s 操作&#xff0c;提升运维效率&#xff0c;为企业云原生转型推…...

华为深度学习面试手撕题:手写nn.Conv2d()函数

题目 只允许利用numpy包&#xff0c;实现Pytorch二维卷积函数nn.Conv2d() 解答 此代码考察二维卷积的概念&#xff0c;详见&#xff1a; 6.2. 图像卷积 — 动手学深度学习 2.0.0 documentation 6.3. 填充和步幅 — 动手学深度学习 2.0.0 documentation 6.4. 多输入多输出通…...

归一化相关

归一化相关问题 归一化方式Batch NormalizationLayer NormalizationInstance NormalizationGroup NormalizationRMSNorm(Root Mean Square Layer Normalization):RMSNorm 和 LayerNorm区别?归一化方式 Batch Normalization 在每一层的输入进行归一化处理,使其在每个批次内…...

STM32Cubemx-H7-17-麦克纳姆轮驱动

前言 --末尾有总体的.c和.h 本篇文章把麦克纳姆轮的代码封装到.c和.h&#xff0c;使用者只需要根据轮子正转的方向&#xff0c;在.h处修改定义方向引脚&#xff0c;把轮子都统一正向后&#xff0c;后面的轮子驱动函数就可以正常了&#xff0c;然后直接调用函数驱动即可。 设…...

机器学习算法-逻辑回归

今天我们用 「预测考试是否及格」 的例子来讲解逻辑回归&#xff0c;从原理到实现一步步拆解&#xff0c;保证零基础也能懂&#xff01; &#x1f3af; 例子背景 假设你是班主任&#xff0c;要根据学生的「学习时间」预测「是否及格」&#xff0c;手上有以下数据&#xff1a;…...

Office 2024免费下载 安装包

各位办公小能手们&#xff0c;你们知道吗&#xff1f;咱们日常办公经常会用到一个超厉害的软件套件&#xff0c;那就是Office&#xff0c;它全称Microsoft Office&#xff0c;是微软公司开发的。这玩意儿能大大提升个人和团队的办公效率&#xff0c;像文档处理、数据分析、演示…...

Linux云计算训练营笔记day18(Python)

# 猜数字游戏: 程序生产一个 1-100的随机数 # 让用户重复去猜测, 直到猜对为止 # 如果用户输入的数字 大于 随机生成的数字 提示 大了 # 如果用户输入的数字 小于 随机生产的数字 提示 小了 # 否则 猜对了 break # 增加需求 最多猜6次,如果没有猜对&#xff0c;提示 你失…...

Git深入解析功能逻辑与核心业务场景流程

一、Git核心功能逻辑架构 #mermaid-svg-9tj1iCr99u6QenJM {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-9tj1iCr99u6QenJM .error-icon{fill:#552222;}#mermaid-svg-9tj1iCr99u6QenJM .error-text{fill:#552222;st…...

Opencv4 c++ 自用笔记 03 滑动条、相机与视频操作

1. 相机与视频操作 1.1 打开视频&#xff0f;相机 OpenCV 中 imread() 只能读取静态图像&#xff0c;若要读取视频文件或摄像头流&#xff0c;需要使用 VideoCapture 类&#xff1a; // 构造函数 cv::VideoCapture::VideoCapture(); cv::VideoCapture…...

LINUX528 重定向

2>&1 我的理解&#xff1a; 2>&1&#xff0c;2stderr错误输出&#xff0c;1stdout输出&#xff0c;stderr一般和stdout是分别输出&#xff08;管道符只传递stdout&#xff0c;据元宝&#xff0c;stderr默认输出到终端&#xff1b;如果重定向符不进行2显示重定向&…...

研华工控机安装Windows10系统,适用UEFI(GPT)格式安装

主要硬件 主板&#xff1a;AIMB-787 、CPU&#xff1a;i5-6500 U盘启动工具&#xff1a;通过网盘分享的文件&#xff1a;rufus-3.20.zip 链接: https://pan.baidu.com/s/1YlFfd-_EhFHCG4sEHBQ8dQ?pwdQT12 提取码: QT12 Win10 22H2 Pro 纯净版系统&#xff1a;通过网盘分享…...

1、树莓派更换软件下载源

树莓派官方系统raspbian自带的是国外的软件源&#xff0c;在国内使用经常会遇到无法下载软件的问题。 以下是把raspbian系统&#xff08;buster版本&#xff09;的下载源改为阿里云软件源的方法。 1、修改sources.list文件 sudo nano /etc/apt/sources.list 将初始化中的代…...

历年中山大学计算机保研上机真题

历年中山大学计算机保研上机真题 2025中山大学计算机保研上机真题 2024中山大学计算机保研上机真题 2023中山大学计算机保研上机真题 在线测评链接&#xff1a;https://pgcode.cn/school 不连续1的子串 题目描述 给定一个数字 n n n&#xff0c;输出长度为 n n n 的 01…...

Python----目标检测(《SSD: Single Shot MultiBox Detector》论文和SSD的原理与网络结构)

一、SSD&#xff1a;单次多框检测器 1.1、基本信息 标题&#xff1a;SSD: Single Shot MultiBox Detector 作者&#xff1a;Wei Liu (UNC Chapel Hill), Dragomir Anguelov (Zoox Inc.), Dumitru Erhan, Christian Szegedy (Google Inc.), Scott Reed (University of Michiga…...

springboot集成websocket给前端推送消息

一般通常情况下&#xff0c;我们都是前端主动朝后端发送请求&#xff0c;那么有没有可能&#xff0c;后端主动给前端推送消息呢&#xff1f;这时候就可以借助websocket来实现。下面给出一个简单的实现样例。 首先创建一个websocketDemo工程&#xff0c;该工程的整体结构如下&a…...

DrissionPage SessionPage模式:轻量级HTTP请求的利器

引言 在Python自动化领域&#xff0c;DrissionPage以其创新的三模式设计脱颖而出。作为专为HTTP请求优化的SessionPage模式&#xff0c;凭借其轻量级架构和高效性能&#xff0c;成为API调用、数据采集等场景的首选方案。本文将深入解析SessionPage的技术特性、核心优势及典型应…...

0527漏洞原理:XSS笔记

理论知识 01 前端基础知识 1.1 HTML基础 定义&#xff1a;HTML&#xff08;超文本标记语言&#xff09;用于描述网页结构。标准结构&#xff1a; 内嵌脚本&#xff1a; <script>JavaScript代码</script>1.4 JavaScript弹窗函数 函数描述alert("文本&quo…...

智能制造之精读——RPA制造行业常见场景【附全文阅读】

RPA 在制造行业应用广泛&#xff0c;为企业带来显著价值&#xff0c;是极具潜力的智能化解决方案。它能节省成本&#xff0c;降低人力与管理成本&#xff1b;提升运营效率&#xff0c;减少人机交互损耗&#xff1b;提高质量&#xff0c;保障流程准确性&#xff1b;还能增强合规…...

spark shuffle的分区支持动态调整,而hive不支持

根据Spark官方文档&#xff0c;Spark Shuffle分区支持动态调整的核心原因在于其架构设计和执行模型的先进性&#xff1a; 1. 自适应查询执行&#xff08;AQE&#xff09;机制 Spark 3.0引入的AQE特性允许在运行时动态优化执行计划&#xff0c;包括Shuffle分区调整&#xff1a…...

网络安全十大漏洞

1️⃣ 失效的访问控制&#xff08;Broken Access Control&#xff09; 核心问题&#xff1a;用户能访问本应被禁止的资源或操作 攻击案例&#xff1a; 修改URL参数&#xff1a;https://shop.com/order?user_id100 → 改为 user_id101 查看他人订单 直接访问管理员页面&#…...

关于uv 工具的使用总结(uv,conda,pip什么关系)

最近要开发MCP 项目&#xff0c;uv工具使用是官方推荐的方式&#xff0c;逐要了解这个uv工具。整体理解如下&#xff1a; 一.uv工具的基本情况 UV 是一个由 Rust 编写的现代化 Python 包管理工具&#xff0c;旨在通过极速性能和一体化功能替代传统工具&#xff08;如 pip、vi…...

深入剖析 Docker 容器化原理与实战应用,开启技术新征程!

文章目录 前言一、为什么 是Docker &#xff1f;二、Docker 容器化原理分析2.1 镜像&#xff08;Image&#xff09;2.2 容器&#xff08;Container&#xff09;2.3 仓库&#xff08;Registry&#xff09; 三、Docker 容器化实践3.1 Docker安装3.2 创建一个 Docker 镜像3.3 运行…...

Xamarin劝退之踩坑笔记

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…...

计算机网络(4)——网络层

1.概述 1.1 网络层服务 (1) 网络层为不同主机(Host)之间提供了一种逻辑通信机制 (2)每个主机和路由器都运行网络层协议 发送方&#xff1a;将来自传输层的消息封装到数据报(datagram)中接收方&#xff1a;向传输层交付数据段(segment) 1.2 网络层核心功能 路由选择(routing…...

java 多线程中的volatile关键字作用

文章目录 前置作用一&#xff1a;多线程下&#xff0c;保证可见性作用二&#xff1a;多线程下&#xff0c;禁止指令重排序 前置 保证可见性和保证没有指令重排导致的问题 但是不保证原子性 volatile 常常见到和 static 一起使用&#xff0c;因为 volatile 用在多线程中共享变…...

ESP32基础知识1:项目工程建立和烧录

ESP32基础知识1&#xff1a;项目工程建立和烧录 一、本文内容与前置知识点1. 本文内容2. 前置知识点 二、新建工程1. 工程配置2. 依照模板建立项目 三、硬件烧录1. 硬件准备2. 烧录器和ESP32连接3. 电脑端设置4. 烧录成功演示 四、参考文献 一、本文内容与前置知识点 1. 本文内…...

allWebPlugin中间件VLC专用版之录像功能介绍

背景 VLC控件原有接口是不支持录像的&#xff0c;且libVLC提供的接口库&#xff0c;不能获取录像文件完整名称&#xff08;VLC-3.0.11 录制直播时有的无法保存视频的解决方法 - 1CM - 博客园&#xff09;&#xff1b;因此&#xff0c;非常的不友好。为了能够彻底解决这个问题&a…...

Vim 支持多种编程语言编辑器

软件简介 Vim是Vi编辑器的增强版&#xff0c;它提供了更多的功能和快捷键。Vim是一款自由软件&#xff0c;它是由Bram Moolenaar在1991年创建的。Vim支持多种编程语言&#xff0c;包括C、C、Java、Python、Perl等等。它是一款轻量级的编辑器&#xff0c;可以快速打开和编辑大型…...