Redis内存淘汰

Redis内存淘汰

文章目录

  • Redis内存淘汰
    • Redis可以存储多少数据
    • 淘汰策略
    • 选择哪种淘汰算法
    • LRU
      • 什么是LRU
      • Redis的近似LRU
        • 为什么不直接使用LRU
        • 近似的LRU
        • 淘汰池的优化
        • LRU优化后的对比
    • LFU
      • 什么是LFU
      • 为什么引入LFU
      • Redis的LFU
        • 策略
        • 访问频率衰减
        • 频率更新

Redis可以存储多少数据

maxmemory配置,默认是注释掉的。

#maxmemory <bytes>

我们可以主动配置maxmemory,maxmemory支持各种单位,默认是字节

maxmemory 1024
maxmemory 1024KB
maxmemory 1024MB
maxmemory 1024GB

当Redis存储超过这个值,就会触发内存淘汰。

淘汰策略

有两个方向,一个是noevicition,默认就是这种策略,如果内存达到maxmemory,则写入操作失败,但不会淘汰原有数据;另一个是多种淘汰策略,主要是LRU、LFU、RANDOM、TTL。

image-20240822215406391

LRU(Least recently used,最近最少使用):尝试回收最长时间未使用的。

LFU(Least Frequently Use,最近最少频率使用):尝试回收最不常用的键。

Random:随机回收键。

TTL:回收过期集合的键,并且优先回收存活时间较短(TTL)的键。

一般四种策略又分为volatile,设置了过期时间的Key;或是allkeys,全部的Key。

选择哪种淘汰算法

一般根据业务需求决定,缓存场景下一般使用的是LRU或LFU。

LRU

什么是LRU

最近最久未使用,即记录每个Key的最近访问时间,维护一个访问时间的数据

Redis的近似LRU

为什么不直接使用LRU

因为对所有数据用一个双向链表维护就是一个巨大的成本,Redis本身就是使用内存的,而内存是又少又珍贵的资源,所以Redis选择实现一个近似LRU。

近似的LRU

LRU模式中,RedisObject中lru字段存储的是被访问时的时间,每次该key被访问就会更新这个字段。

llru字段表示的时间戳越小,代表key空闲的时间越长,越应该被淘汰

为了保证高性能,Redis还缓存了Unix操作系统的时钟。

近似的LRU算法中,在内存不足时就会,进行全局随机采样,来筛选准备淘汰的元素。

步骤为:

1.随机采样n个key,n默认为5

2.根据时间戳淘汰最旧的key

3.判断内存是否不足,不足循环步骤1;反之,退出淘汰

之前说的全局随机采样,也是一个范围性的选择。也就是之前提过的,allkeys或者volatile

淘汰池的优化

近似LRU,最大的优点就是节约了内存。但是它的缺点是,淘汰的key是随机采样的结果,并不是真正的全局最久未访问。

在Redis3.0中,对近似LRU进行了优化:加入淘汰池。

优化后的LRU会维护一个大小为16的候选池,池中的数据按时间进行排序。

步骤:

1.第一次是随机挑选的16个,第一次以后就是随机挑选的一个

2.按访问时间进行排序,并且淘汰最久未访问的(一次只淘汰一个,剩下的都在池中)

3.判断是否继续

LRU优化后的对比

image-20240822222328915

浅灰色是被淘汰的数据

灰色是没有被淘汰的老数据

绿色是新加入的数据

我们几乎可以认为Redis的近似LRU已经达到正常LRU的水准了。

LFU

什么是LFU

最不频繁淘汰算法,优先淘汰活跃最低,使用频率最低的。

为什么引入LFU

Redis在4.0版本后引入了LFU算法,为什么?

因为在部分场景下,只根据最近访问,不谈频率得不到我们希望的结果。

比如,有两个键key1、key2,之前9次一直在访问key1,第10次访问了key2,第10次后触发了内存淘汰,那你觉得该淘汰key1还是key2?

如果我们使用LRU,那就是淘汰key1;如果我们使用LFU,那就是淘汰key2。

但是这种场景下,一般我们会期望按频率来进行淘汰,于是就有了LFU

Redis的LFU

策略

我们之前提供Redis的RedisObject中有个字段是lru,其实LFU也是用这个字段来实现的。

LFU和LRU两种策略是一种互斥关系,是不会同时开启的。LFU将这个字段(lru字段24位)拆分为两部分,高16位存储ldt,也就是Last Decrement Time,低8位存储logc logistic Counter。

image-20240823110848798

一个key是否活跃是根据这两个字段决定的。如果一个key,原来访问计数是255,但是一年没访问就会变成0(举例,并不一定是这样);如果一个key,频频被访问,它的访问计数会逐渐变大。

源码中,有部分代码证明了LFU和LRU是共用lru字段的。

#define LFU_INIT_VAL 5
robj *createObject(int type, void *ptr) {robj *o = zmalloc(sizeof(*o));//...//o的初始化//...if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) {o->lru = (LFUGetTimeMinutex()<<8) | LFU_INIT_VAL;}  else {o->lru = LRU_CLOCK();}return o'
}

代码中也说了,如果达到maxmemory,并且策略为LFU,前16位设置时间戳,后8位设置访问频率;否则设置lru当前时间戳。

访问频率衰减

redis.conf文件中,有一项配置为lfu_decay_time,默认值为1,表示每一分钟衰减一次。也就是上一次访问时间距离当前时间的分钟数。

lfu_decay_time 1
频率更新

访问计数的频率是一定概率增加的,次数不到5次,一定增加;如果大于5,小于255,一定概率增加;次数越大,越困难。

当然这也是有配置项的,lfu_log_factor被设置的越大,增加难度就越大,配置为0,每次会必然加1,上限为255(8位)。

void updateLFU(robj *val) {unsigned long counter = LFUDecrAndReturn(val);counter = LFULogIncr(counter);val->lru = (LFUGetTimeMinutes()<<8) | counter;
}

时间更新到高16位,次数更新到低8位。

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

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

相关文章

Docker续4:harbar私有仓库管理

一、新建一台docker&#xff08;192.168.1.77&#xff09;&#xff08;用于上篇创建私有镜像后的测试&#xff08;拉取镜像&#xff09;&#xff09; 运行docker安装脚本 [rootlocalhost ~]# vim /etc/docker/daemon.json //编辑配置文件 { "…

uniapp-Vue项目如何实现国际化,实现多语言切换,拒绝多套开发,一步到位,看这篇就够

一 安装 找到自己的项目,输入cmd进入命令行,输入安装命令,点击回车进行下载: npm install vue-i18nnext 下载完将在项目的配置文件中看到: 二 使用 2.1 在项目中创建一个文件夹如:lang 用于存放不同语言的包。这些语言文件通常为JSON格式 2.2 在项目main.js文件中引入并初…

H264编码原理(一)压缩背后的秘密

一、引言 在当今的数字视频世界中&#xff0c;H.264编码技术无疑占据着至关重要的位置。虽然H.264编码原理可能听起来复杂又深奥&#xff0c;但只要深入了解视频的特性&#xff0c;就能明白为什么它需要如此设计。通过利用视频内容的冗余性和人眼的感知特性&#xff0c;H.264能…

后端面试真题整理

面试问题整理 本人主要记录2024年秋招、春招过程中的疑难八股真题&#xff0c;参考来源&#xff1a;牛客网、知乎等。 八股 深拷贝与浅拷贝 浅拷贝&#xff1a; 浅拷贝会在堆上创建一个新的对象&#xff08;区别于引用拷贝的一点&#xff09;&#xff0c;不过&#xff0c;如果…

黑马JavaWeb开发笔记07——Ajax、Axios请求、前后端分离开发介绍、Yapi详细配置步骤

文章目录 前言一、Ajax1. 概述2. 作用3. 同步异步4. 原生Ajax请求&#xff08;了解即可&#xff09;5. Axios&#xff08;重点&#xff09;5.1 基本使用5.2 Axios别名&#xff08;简化书写&#xff09; 二、前后端分离开发1. 介绍1.1 前后台混合开发1.2 前后台分离开发方式&…

linux下一切皆文件,如何理解?

linux下一切皆文件&#xff0c;不管你有没有学过linux&#xff0c;都应该听过这句话&#xff0c;就像java的一切皆对象一样。 今天就来看看它的真面目。 你记住了&#xff0c;只要一个竞争退出它的PCB要被释放文件名&#xff0c;客服表也要被释放。那么&#xff0c;指向这个文件…

使用代理和 Python 高效进行亚马逊数据抓取: 实用指南

文章目录 一、简介二、为什么要抓取亚马逊&#xff1f;三、了解代理3. 1. 搜索亚马逊的代理类型 四、为什么使用 Python&#xff1f;五、设置5. 1. 选择代理5. 2. 设置代理 六、抓取数据七、解析数据八、 结论 一、简介 在现代数字环境中&#xff0c;分析网络流量对于优化网站…

YOLOv10:实时端到端目标检测

摘要 https://arxiv.org/pdf/2405.14458 近年来&#xff0c;YOLO系列模型因其在计算成本与检测性能之间的有效平衡&#xff0c;在实时目标检测领域占据了主导地位。研究人员在YOLO的架构设计、优化目标、数据增强策略等方面进行了探索&#xff0c;并取得了显著进展。然而&…

RabbitMQ的基础概念介绍

MQ的三大特点&#xff1a;削峰、异步、解耦 1.RabblitMQ概念介绍 1.1概念 RabbitMQ是由erlang语言开发&#xff0c;基于AMQP&#xff08;Advanced Message Queue 高级消息队列协议&#xff09;协议实现的消息队列&#xff0c;它是一种应用程序之间的通信方法&#xff0c;消息…

【管理型文档】软件需求管理过程(原件)

软件需求管理规程应明确需求收集、分析、确认、变更控制及验证等流程&#xff0c;确保需求准确反映用户期望&#xff0c;支撑软件开发。该规程要求系统记录需求来源&#xff0c;通过评审确保需求完整、清晰、无歧义&#xff0c;实施变更控制以维护需求基线稳定&#xff0c;并持…

JVM类加载机制—类加载器和双亲委派机制详解

一、概述 上篇我们介绍了JVM类加载机制—JVM类加载过程&#xff0c;类加载过程是类加载机制第一阶段&#xff0c;这一阶段主要做将类的字节码&#xff08;class文件&#xff09;加载JVM内存模型中&#xff0c;并转换为JVM内部的数据结构&#xff08;如java.lang.Class实例&…

软件测试——自动化测试selenium常用函数

目录 元素的定位cssSelectorxpath函数 操作测试对象窗口切换窗口窗口设置大小窗口切换屏幕截图关闭窗口 等待强制等待隐式等待显示等待 浏览器导航弹窗警告弹窗确认弹窗提示弹窗 文件上传浏览器参数设置 元素的定位 web⾃动化测试的操作核⼼是能够找到⻚⾯对应的元素&#xff0…

【操作系统】14.I/O设备怎么分配和回收?

5.2 I/O设备怎么分配和回收&#xff1f; 5.2.1 I/O核心子系统 I/O调度 设备保护 假脱机技术&#xff08;SPOOLing技术&#xff09; ​ 输入井和输出井 ​ 输入进程和输出进程 ​ 输入缓冲区和输出缓冲区 设备分配与回收 ​ 设备分配应考虑的因素 ​ 静态分配与动态分配 ​ 设备…

上传文件(用户导入),第二次选择文件时没有反应(可用)

https://gitee.com/y_project/RuoYi-Cloud/issues/I582YB PS&#xff1a;恰好我使用的版本是 支持 handleRemove &#xff0c;所以很容易就解决了

企业如何选型人力资源管理系统?(附HR系统对比分析)

随着企业规模的扩大&#xff0c;人力资源管理系统成为了大中型企业不可或缺的工具。近年来&#xff0c;众多新技术产品层出不穷&#xff0c;这些技术和产品的实际功能和适用性并不明确&#xff0c;大量的新概念和新厂商通过各种渠道宣传&#xff0c;市场上信息过载使得企业难以…

美畅物联丨物联网平台的标准化之路:物模型设计的创新及应用

随着物联网&#xff08;IoT&#xff09;技术以前所未有的迅猛之势蓬勃发展&#xff0c;海量的物联网终端与应用纷纷接入&#xff0c;这不可避免地引发了数据与应用层面的异构化难题&#xff0c;进而形成了复杂且多变的碎片化问题。物联网感知数据因其具备多源异构的显著特性&am…

Linux中的常见命令——时间日期类命令

1、date显示当前时间 基本语法 写法功能描述date显示当前时间date %Y显示当前年份【四位数】date %m显示当前月份date %d显示当前是哪一天date "%Y-%m-%d %H:%M:%S" 显示年月日时分秒 【由于年月日和时分秒中间有空格所以需要用引号引起来】 实操案例 1、显示当…

【VUE入门级温故知新】一文向您详细介绍~组件属性Props(选项式API)

大家好&#xff0c;我是DX3906 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我静心耕耘大前端领域、真诚分享知识与智慧的小天地&#xff01;&#x1f387; 前面和大家分享了《如何从零开始创建一个 Vue 应用》 《VUE模板语法(超详细讲解)》 《一文向您详细介绍~Vu…

uniapp中H5网页怎么实现自动点击事件

<template><view><button ref"myButton" click"handleClick">点击我</button></view> </template><script> export default {mounted() {this.$nextTick(() > {const button this.$refs.myButton;console.l…

并发服务器---IO多路复用

单循环服务器&#xff1a;同一时刻只能处理一个客户端任务 并发服务器&#xff1a; 同一时刻&#xff0c;只能处理多个客户端的任务 实现方法&#xff1a;多进程 多线程 IO多路复用 IO多路复用&#xff1a; 1.阻塞io&#xff08;fgets scanf recv getchar read&#x…