Redis常用内存淘汰策略?

news2024/9/24 5:32:39

淘汰范围来说可以分为不淘汰任何数据、只从设置了到期时间的键中淘汰和从所有键中淘汰三类。而从淘汰算法来分,又主要分为 random(随机),LRU(最近最少使用),以及 LFU(最近最不常使用)三种。

内存总是有限的,因此当 Redis 内存超出最大内存时,就需要根据一定的策略去主动的淘汰一些 key,来腾出内存,这就是内存淘汰策略。我们可以在配置文件中通过 maxmemory-policy 配置指定策略。

与到期删除策略不同,内存淘汰策略主要目的则是为了防止运行时内存超过最大内存,所以尽管最终目的都是清理内存中的一些 key,但是它们的应用场景和触发时机是不同的。

算上在 4.0 添加的两种基于 LFU 算法的策略, Redis 一共提供了八种策略供我们选择:

  • noeviction,不淘汰任何 key,直接报错。它是默认策略**。**
  • volatile-random:从所有设置了到期时间的 key 中,随机淘汰一个 Key。
  • volatile-lru: 从所有设置了到期时间的 key 中,淘汰最近最少使用的 key。
  • volatile-lfu: 从所有设置了到期时间的 key 中,淘汰最近最不常用使用的 key(4.0 新增)。
  • volatile-ttl: 从所有设置了到期时间的 key 中,优先淘汰最早过期的 key。
  • allkeys-random:从所有 key中,随机淘汰一个键(4.0 新增)。
  • allkeys-lru: 从所有 key 中,淘汰最近最少使用的 key。
  • allkeys-lfu: 从所有 key 中,淘汰最近最不常用使用的键。

淘汰范围来说可以分为不淘汰任何数据、只从设置了到期时间的键中淘汰和从所有键中淘汰三类。而从淘汰算法来分,又主要分为 random(随机),LRU(最近最少使用),以及 LFU(最近最不常使用)三种。

其中,关于 LRU 算法,它是一种非常常见的缓存淘汰算法。我们可以简单理解为 Redis 会在每次访问 key 的时候记录访问时间,当淘汰时,优先淘汰最后一次访问距离现在最早的 key。

而对于 LFU 算法,我们可以理解为 Redis 会在访问 key 时,根据两次访问时间的间隔计算并累加访问频率指标,当淘汰时,优先淘汰访问频率指标最低的 key。相比 LRU 算法,它避免了低频率的大批量查询造成的缓存污染问题

顺带一提,只要是有类似缓存机制的应用或多或少都会面对这种问题,比如老生常谈的 MySQL 连表查询,在数据量大的时候也会造成缓存污染。

LRU 的实现

LRU 的全称为 Least Recently Used,也就是最近最少使用。一般来说,LRU 会从一批 key 中淘汰上次访问时间最早的 key。

它是一种非常常见的缓存回收算法,在诸如 Guava CacheCaffeine等缓存库中都提供了类似的实现。我们自己也可以基于 JDK 的 LinkedHashMap 实现支持 LRU 算法的缓存功能。

传统的 LRU 算法实现通常会维护一个链表,当访问过某个节点后就将该节点移至链表头部。如此反复后,链表的节点就会按最近一次访问时间排序。当缓存数量到达上限后,我们直接移除尾节点,即可移除最近最少访问的缓存。

近似 LRU

Redis 中的 LRU 是近似 LRU(NearlyLRU)。当每次访问 key 时,Redis 会在结构体中记录本次访问时间,而当需要淘汰 key 时,将会从全部数据中进行抽样,然后再移除样本中上次访问时间最早的 key。

它的特点是:

  • 仅当需要时再抽样,因而不需要维护全量数据组成的链表,这避免了额外内存消耗。
  • 访问时仅在结构体上记录操作时间,而不需要操作链表节点,这避免了额外的性能消耗。

当然,有利就有弊,这种实现方式也决定 Redis 的 LRU 是并不是百分百准确的,被淘汰的 key 未必真的就是所有 key 中最后一次访问时间最早的。

#a. 抽样大小

根据上述的内容,我们不难理解,当抽样的数量越大,LRU 淘汰 key 就越准确,相对的开销也更大。因此,Redis 允许我们通过 maxmemory-samples 配置采样数量(默认为 5),从而在性能和精度上取得平衡。

#b. 缓存污染

LRU 有个最大问题,就是它只认最近一次访问时间。而如果出现系统偶尔需要一次性读取大量数据的时候,会大规模更新 key 的最近访问时间,从而导致真正需要被频繁访问的 key 因为最近一次访问时间更早而被直接淘汰。这种情况被称为缓存污染

如何选择

软件工程没有银弹,我们不可能指望存在一个能完美适用于所有场景的内存淘汰策略。

在实际场景中,我们需要结合业务特点、数据量大小、数据的冷热……等多个维度来选择合适的淘汰策略。

比如:

  • 当使用 Redis 来缓存用户动态时,由于热门用户的动态相对于普通用户往往会被更高频的访问,因此我们可以选择基于 LRU 或者 LFU 算法的策略保证热点数据不会被轻易淘汰。
  • 当使用 Redis 缓存菜单树时,由于菜单树数据大部分情况下没有明确的热点区分,因此可以考虑使用随机淘汰策略平衡各个数据的访问频率。

当然,调整淘汰策略也只是优化方案的一种。条件允许的话,在特定情况下直接增加内存、将单机改为集群或者缓存预热同样可以带来显著的收益。

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

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

相关文章

【AI美图】第03期效果图,AI人工智能全自动绘画,二次元美图欣赏

带来一组二次元人工智能自动绘图 对比分析: 标题手画二次元需要技巧: 二次元高清图片的绘制技巧主要包括以下几点: 线条的运用:在二次元风格的绘画中,线条的运用非常重要。要绘制出流畅、细腻的线条,需…

VBA技术资料MF96:单字段多条件高级筛选

我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。我的教程一共九套,分为初级、中级、高级三大部分。是对VBA的系统讲解,从简单的入门,到…

基于CNN+数据增强+残差网络Resnet50的少样本高准确度猫咪种类识别—深度学习算法应用(含全部工程源码)+数据集+模型(六)

系列文章目录 基于CNN数据增强残差网络Resnet50的少样本高准确度猫咪种类识别—深度学习算法应用(含全部工程源码)数据集模型(一) 基于CNN数据增强残差网络Resnet50的少样本高准确度猫咪种类识别—深度学习算法应用(含全部工程源码)数据集模型&#xf…

Day10 Liunx高级系统设计11-数据库2

DQL:数据查询语言 查询全表 select * from 表名; 查询指定列 select 列名 1, 列名 2,… from 表名 ; 条件查询 select * from 表名 where 条件 ; 注意: 条件查询就是在查询时给出 WHERE 子句,在 WHERE 子句中可以使用如下运算符及关键 字&#…

学习笔记10——Mysql的DDL语句

学习笔记系列开头惯例发布一些寻亲消息 链接:https://baobeihuijia.com/bbhj/contents/3/197161.html 数据库创建: CREATE DATABASE books; CREATE DATABASE IF NOT EXISTS books;更改字符集 ALTER DATABASE books CHARACTER SET gbk;库的删…

三层交换与DHCP

目录 一、三层交换 (一)基本概念 (二)转发原理 (三)ensp项目实验 二、DHCP (一)DHCP工作原理 1.DHCP的特点 2.工作原理 (二)DHCP项目实验 一、三层交…

电商用户运营优化:腾讯文档API无代码集成

腾讯文档API集成:电商平台无代码客服系统 随着数字化时代的到来,电商平台日益求势于高效率和低成本的运营模式。无代码开发正在改变传统业务流程的构建方式,尤其在客户服务领域,这种转变正变得尤为明显。本文将探索腾讯文档API在…

大模型算法工程师的面试题来了(附答案)

自 ChatGPT 在去年 11 月底横空出世,大模型的风刮了整一年。 历经了百模大战、Llama 2 开源、GPTs 发布等一系列里程碑事件,将大模型技术推至无可争议的 C 位。基于大模型的研究与讨论,也让我们愈发接近这波技术浪潮的核心。 最近大模型相关…

【QT】时间日期与定时器

目录 1.时间日期相关的类 2.日期时间数据与字符串之间的转换 2.1 时间、日期编辑器属性设置 2.2 日期时间数据的获取与转换为字符串 2.3 字符串转换为日期时间 3.QCaIendarWidget日历组件 3.1基本属性 3.2 公共函数 3.3 信号 4.实例程序演示时间日期与定时器的使用 …

创建型模式之工厂方法模式

一、概述 1、工厂方法模式:定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类 2、工厂方法模式:不再提供一个按钮工厂类来统一负责所有产品的创建,而是将具体的按钮创建过程交…

一文弄懂自编码器 -- Autoencoders

1. 引言 近年来,自编码器(Autoencoder)一词在许多人工智能相关的研究论文、期刊和学位论文中被频繁提及。自动编码器于1980年推出,是一种用于神经网络的无监督学习技术,可以从未被标注的训练集中学习。 本文重点介绍…

谣言检测常用数据集汇总

Pheme-R 获取地址:https://figshare.com/articles/dataset/PHEME_rumour_scheme_dataset_journalism_use_case/2068650 PHEME社交媒体谣言数据集:这些谣言与9条不同的突发新闻有关。它是为分析社交媒体谣言而创建的,并包含由谣言推文发起的推特对话;这些…

设计模式——装饰模式(结构型)

引言 装饰模式是一种结构型设计模式, 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。 假设你正在开发一个提供通知功能的库, 其他程序可使用它向用户发送关于重要事件的通知。 库的最初版本基于 通知器Notifier类,…

jmeter,http cookie管理器

Http Cookie管理器自动实现Cookie关联的原理: (默认:作用域在同级别的组件) 一:当Jmeter第1次请求服务器的时候,如果说服务器有通过响应头的Set-Cookie有返回Cookie,那么Http Cookie管理器就会自动的保存这些Cookie的值。 二:当Jmeter第2-N次请求服务器的…

uniapp框架——初始化vue3项目(搭建ai项目第一步)

文章目录 ⭐前言💖 小程序系列文章 ⭐uniapp创建项目💖 初始化项目💖 uni实例生命周期💖 组件生命周期💖 页面调用💖 页面通讯💖 路由 ⭐搭建首页⭐form表单校验页面⭐总结⭐结束 ⭐前言 大家好…

01_Web开发基础之HTML+CSS

Web开发基础之HTMLCSS 学习目标和内容 1、能够描述Web开发需要的技术点 2、能够描述HTML的作用 3、能够实现一个列表 4、能够实现创建一个表格 5、能够实现一个表单 6、能够描述CSS的作用 7、能够使用选择器获取到标签 8、能够使用CSS设置字体的颜色和大小 一、Web开发相关介绍…

Linux Shell——如何书写shell脚本的第一步!!!

Shell脚本 1. #!2. 如何执行一个shell脚本3. 如何在Shell文件中包含其他脚本文件 总结 这篇文章没有关于shell特别的语法知识,只是总结一下关于shell脚本文件的一些书写规定和如何执行一个shell脚本,如何在一个shell脚本中引入其他的shell脚本…

八、Seata的XA模式

目录 八、Seata的XA模式8.3 XA模式多数据源场景1 环境搭建2、使⽤XA模式解决事务 八、Seata的XA模式 8.3 XA模式多数据源场景 1 环境搭建 建库建表 代码的db.sql中 创建工程 添加依赖 <dependency><groupId>org.springframework.boot</groupId><ar…

C#动态生成带参数的小程序二维码

应用场景 在微信小程序管理后台&#xff0c;我们可以生成下载标准的小程序二维码&#xff0c;提供主程序入口功能。在实际应用开发中&#xff0c;小程序二维码是可以携带参数的&#xff0c;可以动态进行生成&#xff0c;如如下场景&#xff1a; 1、不同参数决定的显示界面不同…

LED 底层原理 和 GPIO引脚、寄存器操作

目录 LED 原理 LED 的驱动方式 普适的 GPIO 引脚操作方法 GPIO 寄存器操作 LED 原理 当我们学习 C 语言的时候&#xff0c;我们会写个 Hello 程序。 那当我们写 ARM 程序&#xff0c;也该有一个简单的程序引领我们入门&#xff0c;这个程序就是点亮 LED。 我们怎样去点亮…