Redis淘汰策略详解!

在这里插入图片描述

目录

    • 一、为什么需要淘汰策略? 🤔
    • 二、Redis 的淘汰策略详解 👇
    • 三、如何选择合适的淘汰策略? 🤔➡️✅
    • 四、如何切换 Redis 的淘汰策略? ⚙️🔧
    • 五、总结 🎉

🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,可以多多支持一下,感谢🤗!

🌟了解 Redis 大 Key解决方案 请看 : Redis 大 Key:别让你的 Redis 变成“胖子”!

其他优质专栏: 【🎇SpringBoot】【🎉多线程】【🎨Redis】【✨设计模式专栏(已完结)】…等

如果喜欢作者的讲解方式,可以点赞收藏加关注,你的支持就是我的动力
✨更多文章请看个人主页: 码熔burning

一、为什么需要淘汰策略? 🤔

Redis 是一种基于内存的数据库,速度飞快 🚀,但内存可是宝贵的资源!💰 当 Redis 实例使用的内存达到了你配置的上限 (maxmemory 指令设置的值) 时,就不能再无限制地存新数据了。如果不做处理,后续的写入操作可能会导致 Redis 内存溢出 (OOM),甚至让服务挂掉 💥。

为了优雅地处理这种情况,Redis 提供了多种内存淘汰策略。当内存告急 🚨 时,Redis 会根据你选定的策略,自动删除一些“不那么重要”的键(Key),腾出空间来迎接新的数据。

注意: 如果你没有设置 maxmemory (或者设为 0),Redis 会尝试吃掉所有能用的内存,并且不会触发任何淘汰策略。这种情况下,物理内存耗尽时,操作系统可能会出手干预,把 Redis 进程给“咔嚓”掉。😱

二、Redis 的淘汰策略详解 👇

Redis 提供了以下几种主要的淘汰策略 (可以通过 maxmemory-policy 配置项设置):

  1. noeviction (默认策略) 🙅‍♀️

    • 行为: 当内存满时,任何想写入更多数据的命令(如 SET, LPUSH 等,但 DEL 和一些只读命令除外)都会直接报错 ❌。它不会删除任何现有键。
    • 含义: 就是不删!宁可报错,也绝不丢数据。
    • 适用场景:
      • 数据极其重要,一丝一毫都不能丢。
      • 应用层有完善的错误处理和降级机制。
      • 主要用作持久化存储,而不是临时缓存。
  2. allkeys-lru (Least Recently Used - 最近最少使用) ⏰

    • 行为: 内存不足时,在所有键中,把那个最久没被访问(读或写)的键给请出去。
    • 含义: 优先保留“热乎”的数据,认为刚用过的以后还会用。
    • 适用场景:
      • 最常见、最通用的策略之一,适合绝大多数缓存场景 👍。
      • 你的应用访问模式符合“热点数据”原则(刚访问的,可能马上又会被访问)。
      • 不知道选啥好的时候,选它一般没错。
  3. volatile-lru

    • 行为: 内存不足时,只在那些设置了过期时间 (TTL) 的键里,找那个最久没被访问的键淘汰掉。
    • 含义: 只在“临时工”(设置了过期时间的键,通常是缓存)里搞淘汰,保护那些“正式工”(没设过期时间的持久键)。
    • 适用场景:
      • 想明确区分缓存数据和需要长期保存的数据。
      • 把 Redis 同时当缓存(设 TTL)和少量持久存储(不设 TTL)用。
  4. allkeys-random 🎲

    • 行为: 内存不足时,在所有键中,闭着眼睛随机抓一个删掉。🤷‍♂️
    • 含义: 完全随机,不看情面(访问模式、过期时间)。
    • 适用场景:
      • 应用的访问模式极其随机,或者你压根不在乎删了哪个。
      • 对淘汰的精确性要求不高,追求极低的淘汰开销。
      • 所有键的被访问概率都差不多。
  5. volatile-random 🎰

    • 行为: 内存不足时,只在设置了过期时间 (TTL) 的键里,随机抓一个删掉。
    • 含义: 只在“临时工”里随机淘汰,保护“正式工”。
    • 适用场景:
      • volatile-lru 类似,想区分缓存和持久数据,但在缓存内部,访问模式不重要或很随机,用随机淘汰省点力气。
  6. volatile-ttl

    • 行为: 内存不足时,在设置了过期时间 (TTL) 的键里,找那个剩余寿命 (Time To Live) 最短 的键删掉。
    • 含义: 优先淘汰那些马上就要“寿终正寝”的键,可以认为它们价值最低。
    • 适用场景:
      • 缓存数据有明确的生命周期,希望先清理快到期的。
      • 希望缓存里尽量都是“新鲜出炉”的数据。
  7. allkeys-lfu (Least Frequently Used - 最不经常使用) 🔥 (Redis 4.0+ 新增)

    • 行为: 内存不足时,在所有键中,把那个访问次数最少的键淘汰掉。
    • 含义: 优先保留“人气王”(访问频率高的数据),认为访问次数比最近访问时间更能体现价值。LFU 会默默记录每个键被访问了多少次。
    • 适用场景:
      • 缓存场景中,有些数据可能偶尔才用,但一用就很关键(比如配置项);而有些数据可能短时间刷一波访问量就没用了。LFU 更擅长保留前者。
      • 访问模式更符合“用得多就是爷”原则。
  8. volatile-lfu 👍 (Redis 4.0+ 新增)

    • 行为: 内存不足时,只在设置了过期时间 (TTL) 的键里,找那个访问次数最少的键淘汰掉。
    • 含义: 只在“临时工”里按访问频率淘汰,保护“正式工”,并优先保留人气高的缓存。
    • 适用场景:
      • allkeys-lfu 类似,但需要保护没设置过期时间的持久键。适合混合存储,且缓存数据的访问频率是决定去留的关键。

💡 重要提示:近似 LRU 和 LFU

为了效率,Redis 实现的 LRU 和 LFU 都不是绝对精确的。它们用了近似算法:Redis 会随机挑一小撮键(默认 5 个,通过 maxmemory-samples 参数配置),然后从这堆里面选出最符合策略(最老、最少用等)的那个来淘汰。样本量越大,越接近精确,但 CPU 开销也越大。对大多数应用,默认值就挺好用了!

三、如何选择合适的淘汰策略? 🤔➡️✅

选哪个策略,得看你的应用场景和数据戏份:

  1. 通用缓存,不确定访问模式?

    • 试试 allkeys-lru 吧!它是老牌明星,通常效果不错。🌟
  2. 要区分缓存和持久数据?

    • 想保护没设过期时间的“元老”键?用 volatile-lru, volatile-lfu, volatile-random, 或 volatile-ttl
    • 在这些 volatile-* 策略里:
      • 关心谁最近被翻牌子?选 volatile-lru ⏰。
      • 关心谁被翻牌子的次数最多?选 volatile-lfu 🔥 (Redis 4.0+)。
      • 想先送走快到期的?选 volatile-ttl ⏳。
      • 随便删个临时的就行?选 volatile-random 🎰。
  3. 所有数据都是缓存,访问频率比时间更重要?

    • allkeys-lfu 🔥 (Redis 4.0+)。
  4. 所有数据都是缓存,访问随机或不 care 删哪个?

    • allkeys-random 🎲。
  5. 数据宝宝一个都不能少,宁可写入失败?

    • noeviction 🙅‍♀️ (默认)。记得让你的应用能处理好写入错误哦!

四、如何切换 Redis 的淘汰策略? ⚙️🔧

有两种主要方式来设定或切换策略:

  1. 通过配置文件 (redis.conf) ✍️📄

    • 打开你的 redis.conf 文件。
    • 找到或加上 maxmemory-policy 这一行。
    • 把值改成你想要的策略名,比如:
      maxmemory-policy volatile-lru
      
    • 优点: 配置是永久的,Redis 重启后还在。👍
    • 缺点: 改完需要重启 Redis 服务才能生效。🔄
  2. 通过 CONFIG SET 命令 (动态修改) 💻✨

    • 连上 Redis 服务器 (redis-cli)。
    • 执行 CONFIG SET 命令:
      CONFIG SET maxmemory-policy <policy_name>
      
      例如,切换到 allkeys-lfu
      CONFIG SET maxmemory-policy allkeys-lfu
      
    • 可以用 CONFIG GET maxmemory-policy 看看当前是啥策略。
    • 优点: 立刻生效,不用重启 Redis,非常灵活!💨
    • 缺点: 这只是临时修改。Redis 一重启,就又变回 redis.conf 里写的那样了。😅
    • 让动态修改“转正”: 想让动态修改永久生效?执行 CONFIG SET 之后,再执行 CONFIG REWRITE 命令。这会把当前运行的配置写回 redis.conf 文件(前提是 Redis 有权限写这个文件)。
# 示例:动态设置并永久保存
redis-cli
127.0.0.1:6379> CONFIG SET maxmemory-policy allkeys-lru
OK
127.0.0.1:6379> CONFIG REWRITE
OK

五、总结 🎉

理解和选择对的 Redis 淘汰策略,对于优化性能、保证服务稳如老狗 🐕 以及满足业务需求都超级重要!一定要根据你的应用特点和数据访问模式来选型,并通过监控 Redis 内存 (INFO memory) 和淘汰情况 (INFO stats 里的 evicted_keys) 来看看效果怎么样。记住,只有设置了 maxmemory,淘汰策略才会开始工作哦!😉

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

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

相关文章

存储基石:深度解读Linux磁盘管理机制与文件系统实战

Linux系列 文章目录 Linux系列前言一、磁盘1.1 初识磁盘1.2 磁盘的物理结构1.3 磁盘的存储结构1.4 磁盘的逻辑结构 二、文件系统2.1 系统对磁盘的管理2.2 文件在磁盘中的操作 前言 Linux 文件系统是操作系统中用于管理和组织存储设备&#xff08;如硬盘、SSD、USB 等&#xff…

本节课课堂总结

匿名子类&#xff1a; 说明 和 Java 一样&#xff0c;可以通过包含带有定义或重写的代码块的方式创建一个匿名的子类。 单例对象&#xff08;伴生对象&#xff09; Scala语言是完全面向对象的语言&#xff0c;所以并没有静态的操作&#xff08;即在Scala中没有静态的概念&a…

I²C、SPI、UART、CAN 通信协议详解

一、协议基本特性对比 特性ICSPIUARTCAN通信类型同步、半双工同步、全双工异步、全双工异步、多主多从信号线SDA&#xff08;数据&#xff09;、SCL&#xff08;时钟&#xff09;MOSI、MISO、SCK、SS&#xff08;片选&#xff09;TX&#xff08;发送&#xff09;、RX&#xff…

【diffusers 进阶(十五)】dataset 工具,Parquet和Arrow 数据文件格式,load dataset 方法

系列文章目录 【diffusers 极速入门&#xff08;一&#xff09;】pipeline 实际调用的是什么&#xff1f; call 方法!【diffusers 极速入门&#xff08;二&#xff09;】如何得到扩散去噪的中间结果&#xff1f;Pipeline callbacks 管道回调函数【diffusers极速入门&#xff0…

第十三章:持久化存储_《凤凰架构:构建可靠的大型分布式系统》

第十三章 持久化存储 一、Kubernetes存储设计核心概念 &#xff08;1&#xff09;存储抽象模型 PersistentVolume (PV)&#xff1a;集群级别的存储资源抽象&#xff08;如NFS卷/云存储盘&#xff09;PersistentVolumeClaim (PVC)&#xff1a;用户对存储资源的声明请求&#…

以太网安全

前言&#xff1a; 端口隔离可实现同一VLAN内端口之间的隔离。用户只需要将端口加入到隔离组中&#xff0c;就可以实现隔离组内端口之间的二层数据的隔离端口安全是一种在交换机接入层实施的安全机制&#xff0c;旨在通过控制端口的MAC地址学习行为&#xff0c;确保仅授权设备能…

跨域问题前端解决

由于浏览器的同源策略&#xff0c;前后端分离的项目&#xff0c;调试的时候总是会遇到跨域的问题&#xff0c;这里通过修改前端代码解决跨域问题。 首先先查看前端代码的根目录下&#xff0c;有没有vue.config.js文件, 若有&#xff0c;使用方法1&#xff0c;若没有此文件&…

Elasticsearch 报错index_closed_exception

index_closed_exception 是 Elasticsearch 中的一个异常类型&#xff0c;它通常发生在尝试对一个已经被关闭&#xff08;closed&#xff09;的索引执行搜索、写入或其他操作时。在 Elasticsearch 中&#xff0c;索引是用来存储和检索数据的逻辑命名空间&#xff0c;可以将其类比…

LearnOpenGL-笔记-其九

今天让我们完结高级OpenGL的部分&#xff1a; Instancing 很多时候&#xff0c;在场景中包含有大量实例的时候&#xff0c;光是调用GPU的绘制函数这个过程都会带来非常大的开销&#xff0c;因此我们需要想办法在每一次调用GPU的绘制函数时尽可能多地绘制&#xff0c;这个过程就…

PDF预览-搜索并高亮文本

在PDF.js中实现搜索高亮功能可以通过自定义一些代码来实现。PDF.js 是一个通用的、基于Web的PDF阅读器&#xff0c;它允许你在网页上嵌入PDF文件&#xff0c;并提供基本的阅读功能。要实现搜索并高亮显示文本&#xff0c;你可以通过以下几个步骤来完成&#xff1a; 1. 引入PDF…

二叉树——队列bfs专题

1.N叉树的层序遍历 我们之前遇到过二叉树的层序遍历&#xff0c;只需要用队列先进先出的特性就可以达到层序遍历的目的。 而这里不是二叉树&#xff0c;也就是说让节点的孩子入队列时不仅仅是左右孩子了&#xff0c;而是它的所有孩子。而我们看这棵多叉树的构造&#xff0c;它…

Python高级爬虫之JS逆向+安卓逆向1.1节-搭建Python开发环境

目录 引言&#xff1a; 1.1.1 为什么要安装Python? 1.1.2 下载Python解释器 1.1.3 安装Python解释器 1.1.4 测试是否安装成功 1.1.5 跟大神学高级爬虫安卓逆向 引言&#xff1a; 大神薯条老师的高级爬虫安卓逆向教程&#xff1a; 这套爬虫教程会系统讲解爬虫的初级&…

Windows 安装和使用 ElasticSearch

SpringBoot3 整合 Elasticsearch 1. ElasticSearch 1.1 ES &#xff08;1&#xff09;ES 是一个开源的分布式搜索和分析引擎&#xff0c;专为处理大模型数据而设计&#xff0c;它能够实现近乎实时的数据检索、分析和可视化&#xff0c;广泛用于全文搜索、日志分析和监控&…

matplotlib初探

库引入 import matplotlib.pyplot as pltpyplot.figure 创建新图形或激活现有图形

NVM 多版本Node.js 管理全指南(Windows系统)

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、全栈领域优质创作者、高级开发工程师、高级信息系统项目管理师、系统架构师&#xff0c;数学与应用数学专业&#xff0c;10年以上多种混合语言开发经验&#xff0c;从事DICOM医学影像开发领域多年&#xff0c;熟悉DICOM协议及…

实验室预约|实验室预约小程序|基于Java+vue微信小程序的实验室预约管理系统设计与实现(源码+数据库+文档)

实验室预约小程序 目录 基于微信小程序的实验室预约管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、微信小程序前台 2、管理员后台 &#xff08;1&#xff09;管理员登录 &#xff08;2&#xff09;实验室管理 &#xff08;3&#xff09;公告信息管理…

SpringBoot底层-数据源自动配置类

SpringBoot默认使用Hikari连接池&#xff0c;当我们想要切换成Druid连接池&#xff0c;底层原理是怎样呢 SpringBoot默认连接池——Hikari 在spring-boot-autoconfiguration包内有一个DataSourceConfiguraion配置类 abstract class DataSourceConfiguration {Configuration(p…

面试算法高频03-递归

认识递归 递归的概念与特性&#xff1a;递归本质类似循环&#xff0c;是通过函数体进行的循环操作。借助电影《盗梦空间》类比&#xff0c;递归如同主角在不同梦境层穿梭&#xff0c;向下进入不同递归层&#xff0c;向上能回到原来一层&#xff0c;每一层环境和周围元素相似&a…

linux Gitkraken 破解

ubuntu 安装 Gitkraken 9.x Pro 版本_gitcracken.git-CSDN博客

设计模式简述(十一)装饰器模式

装饰器模式 描述基本使用使用 描述 装饰器模式是一种功能型模式 用于动态增强对象的功能 这么一说感觉上和代理模式有些类似 抽象装饰器 要实现原有业务接口&#xff0c;并注入原有业务对象 至于对原有业务对象的调用&#xff0c;可以采用private业务对象 实现业务接口方法的…