内存淘金术:Redis 内存满了怎么办?

欢迎来到我的博客,代码的世界里,每一行都是一个故事


在这里插入图片描述

内存淘金术:Redis 内存满了怎么办?

    • 前言
    • LRU(Least Recently Used)算法
    • LFU(Least Frequently Used)算法
    • 定期淘汰策略
    • 内存淘汰事件通知
    • 最佳实践与常见问题

前言

在 Redis 的世界中,内存是宝贵的资源,但也是有限的。当内存达到极限时,Redis 并不是束手无策,它拥有一套高效的主动淘汰策略,帮助你优雅地解决内存溢出问题。今天,我们将一起揭开 Redis 内存保卫战的序幕,掌握内存满了后的主动淘汰绝招。

LRU(Least Recently Used)算法

LRU算法基于最近使用的原则,认为最近最少使用的数据是可以被淘汰的。具体实现方式是维护一个访问顺序的数据结构,当一个数据被访问时,将其移到数据结构的末尾,表示最近使用过。当需要淘汰数据时,从数据结构的开头选择最久未被访问的数据进行淘汰。

在 Redis 中的应用 - LRU 算法的实现方式:

在 Redis 中,LRU算法的实现主要依赖于内部的volatile-lruallkeys-lru两个配置项。这两个配置项分别对应于仅对设置了过期时间的键使用LRU算法进行淘汰(volatile-lru),以及对所有键使用LRU算法进行淘汰(allkeys-lru)。

  1. volatile-lru配置项:

    • Redis会对设置了过期时间的键使用LRU算法进行淘汰。
    • 当一个键在volatile-lru模式下过期时,Redis会检查最近使用的键,并淘汰最近最少使用的那个键。
    maxmemory-policy volatile-lru
    
  2. allkeys-lru配置项:

    • Redis会对所有键使用LRU算法进行淘汰,不仅包括设置了过期时间的键,还包括没有设置过期时间的键。
    • 当需要淘汰键时,Redis会检查所有键的最近使用情况,并淘汰最近最少使用的那个键。
    maxmemory-policy allkeys-lru
    

这两个配置项可以根据实际需要进行选择。需要注意的是,LRU算法的实现可能会带来一些性能开销,因此在特定场景下,可能需要根据应用的特性和性能要求来选择其他淘汰策略或进行适当的调优。

LFU(Least Frequently Used)算法

LFU(Least Frequently Used)算法基本原理:

LFU算法基于使用频率的原则,认为最不经常使用的数据是可以被淘汰的。具体实现方式是维护一个访问频率计数器,每当一个数据被访问时,对应的频率计数器就会增加。当需要淘汰数据时,选择访问频率最低的数据进行淘汰。

在 Redis 中的应用 - LFU 算法的实现方式:

Redis 从版本4.0开始,引入了对LFU算法的支持。在 Redis 中,LFU算法通过以下配置项进行设置:

maxmemory-policy lfu

设置了maxmemory-policylfu后,Redis 将使用LFU算法进行淘汰。需要注意的是,与LRU不同,LFU算法可能需要占用更多的内存,因为需要维护每个键的使用频率计数器。

在使用LFU算法时,Redis 会维护一个最小堆(min-heap)来存储所有的键值对,根据它们的使用频率进行排序。在进行淘汰操作时,选择频率最低的键进行淘汰。

配置项示例:

maxmemory-policy lfu

这表示 Redis 在达到内存限制时,将使用 LFU 算法进行淘汰。

需要注意的是,LFU 算法在一些特定场景下可能不如其他淘汰算法效果好,具体选择应该根据实际需求和应用场景来决定。

定期淘汰策略

定期淘汰策略:

定期淘汰策略涉及定期扫描数据库,根据一定规则淘汰数据,以确保缓存中的数据始终保持最新。这种策略可以根据一些规则,如过期时间、访问时间等,来判断哪些数据应该被淘汰。以下是一个示例代码,演示了如何通过定期任务淘汰数据:

import redis
import schedule
import time# 连接到 Redis 服务器
redis_client = redis.StrictRedis(host='localhost', port=6379, db=0)# 示例代码 - 定时任务淘汰数据
def periodic_eviction():# 获取所有 Key 列表all_keys = redis_client.keys("*")# 遍历所有 Key,根据一定规则淘汰数据for key in all_keys:# 根据过期时间或其他规则判断是否需要淘汰该数据# 例如:如果数据的过期时间小于当前时间,则执行淘汰操作if redis_client.ttl(key) < 0:redis_client.delete(key)# 每小时执行一次定时淘汰任务
schedule.every().hour.do(periodic_eviction)# 循环执行定时任务
while True:schedule.run_pending()time.sleep(1)

淘汰策略的调整:

如何调整淘汰策略以适应不同的场景取决于具体的应用需求和性能要求。以下是一些可能的调整:

  1. 基于过期时间的淘汰: 如果数据有明确的过期时间,可以优先考虑基于过期时间的淘汰策略,即定期检查并删除已过期的数据。

  2. 基于访问时间的淘汰: 如果应用中的数据访问模式呈现出明显的周期性,可以考虑基于访问时间的淘汰策略。即定期检查并删除最久未被访问的数据。

  3. 动态调整定期任务频率: 可以根据系统负载和性能需求动态调整定期任务的执行频率。例如,在系统负载较低时可以增加淘汰任务的执行频率,而在高负载时可以降低频率,以平衡性能和淘汰效果。

  4. 使用淘汰白名单: 在一些特殊情况下,可以使用淘汰白名单,将一些重要的数据免于淘汰,确保其不会被定期任务误删。

调整淘汰策略时,需要综合考虑数据的特性、应用的访问模式和性能需求,进行灵活而合理的配置。在实际应用中,可以根据监测数据和反馈来不断调整淘汰策略,以满足不同场景下的需求。

内存淘汰事件通知

内存淘汰事件通知:

在 Redis 中,可以使用发布-订阅模式来订阅内存淘汰事件。Redis 会在发生淘汰时发送相应的事件通知,订阅者可以通过监听这些通知来执行相应的处理操作。

以下是一个示例代码,演示了如何订阅和处理内存淘汰事件:

import redis
import threading# 连接到 Redis 服务器
redis_client = redis.StrictRedis(host='localhost', port=6379, db=0)# 订阅内存淘汰事件的频道
eviction_channel = '__keyevent@0__:e'# 订阅者的处理函数
def handle_eviction_message(message):print(f"Received eviction event: {message['data'].decode('utf-8')}")# 启动订阅者线程
def start_subscriber():subscriber = redis_client.pubsub()subscriber.subscribe(eviction_channel)for message in subscriber.listen():if message['type'] == 'message':handle_eviction_message(message)# 启动订阅者线程
subscriber_thread = threading.Thread(target=start_subscriber)
subscriber_thread.start()# 示例代码 - 在 Redis 中设置一些数据,并让 Redis 主动进行淘汰
redis_client.set('key1', 'value1')
redis_client.set('key2', 'value2')
redis_client.set('key3', 'value3')
redis_client.config_set('maxmemory', 10)  # 设置 Redis 内存限制# 主动进行淘汰,会触发内存淘汰事件
redis_client.execute_command('DEBUG', 'OBJECT', 'FREQ', 'key1')

在上述示例中,我们通过订阅__keyevent@0__:e频道来监听内存淘汰事件。在主动设置 Redis 的内存限制后,我们通过设置数据和执行DEBUG OBJECT FREQ命令(主动访问键,模拟对键的访问)来触发内存淘汰事件。淘汰事件的通知将通过订阅者的handle_eviction_message函数进行处理。

处理淘汰事件:

处理淘汰事件的方式取决于应用的需求。在示例中,handle_eviction_message函数简单地打印了接收到的淘汰事件消息。实际中,可以根据淘汰事件的内容执行相应的逻辑,例如记录日志、更新缓存状态等。

需要注意的是,Redis 提供的内存淘汰事件通知并非是精确的事件通知,而是近似通知。淘汰事件通知中的键名是经过采样和近似计算的,可能不包含所有被淘汰的键。因此,在处理淘汰事件时,需要谨慎考虑通知的准确性。

最佳实践与常见问题

选择适用场景的淘汰策略:

不同的业务场景可能适用不同的淘汰策略,根据具体的应用需求和数据访问模式进行选择。以下是一些场景和适用的淘汰策略的示例:

  1. 时效性数据场景:

    • 适用淘汰策略: TTL(Time To Live)机制,基于数据的时效性设置合理的过期时间。
    • 理由: 适用于需要定期刷新数据的场景,确保数据不会因长时间未更新而失效。
  2. 高访问频率数据场景:

    • 适用淘汰策略: LRU(Least Recently Used)算法。
    • 理由: 适用于高频访问的数据,确保经常被访问的数据保持在缓存中,提高命中率。
  3. 频繁更新数据场景:

    • 适用淘汰策略: 定时刷新策略。
    • 理由: 适用于数据更新频繁的场景,通过定时刷新保持缓存中的数据与底层数据源同步。
  4. 节约内存场景:

    • 适用淘汰策略: LFU(Least Frequently Used)算法。
    • 理由: 适用于需要节约内存的场景,淘汰不经常使用的数据,优先保留常用数据。

处理淘汰异常:

在淘汰过程中可能出现一些异常情况,以下是一些可能的问题及解决方案:

  1. 淘汰过程中的性能问题:

    • 问题: 频繁淘汰导致性能下降。
    • 解决方案: 考虑调整淘汰的频率、选择更高效的淘汰算法,或者采用异步淘汰的方式,将淘汰操作放入后台进行。
  2. 淘汰导致的数据不一致:

    • 问题: 淘汰操作导致缓存中的数据与底层数据源不一致。
    • 解决方案: 采用合适的淘汰策略,避免淘汰频繁使用的数据,或者在淘汰后及时从底层数据源重新加载数据。
  3. 异常淘汰策略选择:

    • 问题: 错误选择了不适合场景的淘汰策略。
    • 解决方案: 定期评估系统的数据访问模式和特性,根据实际需求选择合适的淘汰策略,进行动态调优。
  4. 内存不足导致淘汰失败:

    • 问题: 在内存不足的情况下,淘汰操作无法释放足够内存。
    • 解决方案: 考虑调整淘汰策略,增加内存限制,或者通过升级硬件来解决内存不足的问题。

在处理淘汰异常时,了解业务场景、监控淘汰过程并及时调整配置是关键。深入理解淘汰策略及其影响,能够有效地应对各种潜在的问题。

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

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

相关文章

vulhub中的Nginx 文件名逻辑漏洞(CVE-2013-4547)

目录 Nginx 文件名逻辑漏洞&#xff08;CVE-2013-4547&#xff09; 1.cd到CVE-2013-4547 2.执行docker-compose up -d 3.查看靶场是否开启成功 4.访问浏览器 5.上传含有一句话木马的图片 6.burp抓包 7.在shell.gif加空格 8.放包 9.访问路径 10.继续抓包 11.在aa后面…

EasyExcel简单实例

EasyExcel简单实例 准备工作场景一&#xff1a;读取 Student 表需求1&#xff1a;简单读取需求2&#xff1a;读取到异常信息时不中断需求3&#xff1a;读取所有的sheet工作表需求4&#xff1a;读取指定的sheet工作表需求5&#xff1a;从指定的行开始读取 场景二&#xff1a;写入…

鸿蒙原生应用再添新丁!京东入局鸿蒙

鸿蒙原生应用再添新丁&#xff01;京东入局鸿蒙 来自 HarmonyOS 微博1月10日消息&#xff0c;#京东启动鸿蒙原生应用开发#&#xff01;优惠信息、派送进度都可以随时随地便捷查询。双方将携手为消费者带来全场景“多快好省”购物体验&#xff0c;更智能&#xff0c;更贴心&…

Java多线程并发篇----第七篇

系列文章目录 文章目录 系列文章目录前言一、说一说自己对于 synchronized 关键字的了解二、说说自己是怎么使用 synchronized 关键字,在项目中用到了吗?synchronized关键字最主要的三种使用方式三、什么是线程安全?Vector是一个线程安全类吗?四、volatile关键字的作用?前…

将WebGL打包的unity项目部署至Vue中

一、webgl打包 创建一个空项目&#xff08;或者直接使用现成的项目都可以&#xff09;这里以该空项目为例子 注意&#xff1a; 如果你的unity项目中有文字&#xff0c;不需要使用unity默认的字体&#xff0c;需要更改它的字体&#xff0c;否则在最后生成的页面中会显示不出来…

【NVIDIA】Jetson Orin Nano系列:烧写Ubuntu22.04

1、简介 最新的sdk-manager已经可以安装到Ubuntu22.0&#xff0c;也支持在 Jetson Orin Nano 上烧写Ubuntu22.04。 官网介绍&#xff1a;https://developer.nvidia.com/sdk-manager 2、版本介绍 JetPack版本&#xff1a;https://developer.nvidia.com/embedded/jetpack-ar…

读《Mixtral of Experts》

摘要 稀疏混合专家&#xff08;SMoE&#xff09; 语言模型Mixtral 8x7B&#xff08;那大概可以理解成他是一个缝合怪&#xff0c;把所有的任务模型缝合到一起&#xff0c;然后有一个类似打分投票的路由机制来针对输入问题选择任务子模型从而得到针对性的结果。&#xff09;。Mi…

免费简单好用的 webshell 在线检测:支持 php、jsp、asp等多格式文件

话不多说&#xff0c;直接上图上链接&#xff1a;https://rivers.chaitin.cn/?share3d4f2e8aaec211eea5550242c0a8170c 还是比较好用的&#xff0c;支持 PHP、JSP 文件 webshell 检测&#xff0c;看官方解释文档&#xff0c;引擎使用静态文本特征、骨架哈希、静态语义分析、动…

uniapp使用wxml-to-canvas开发小程序保存canvas图片

微信小程序官方解决方案&#xff1a;wxml-to-canvas 使用wxml-to-canvas要知道一些前提条件 1、只能画view&#xff0c;text&#xff0c;image 2、每个元素必须要设置宽高 3、默认是flex布局&#xff0c;可以通过flexDirection: "column"来改变排列方式 4、文字 必…

Tomcat 部署

技能目标&#xff1a; 了解 Tomcat 熟悉 Tomcat 多虚拟主机环境 8.1 Tomcat 概述 自 2017 年 11 月编程语言排行榜 Java 占比 13% &#xff0c;高居榜首&#xff0c; Tomcat 也一度成为 Java 开发人员的首选。其开源、占用系统资源少、跨平台等特性深受广大程序员…

Codeforces Hello 2024 A~F1

A.Wallet Exchange(思维) 题意&#xff1a; Alice和Bob各自拥有 a , b a,b a,b枚硬币&#xff0c;他们决定以Alice为先手开始比赛&#xff0c;比赛中每人在每轮需按顺序执行操作1和操作2&#xff1a; 操作1&#xff1a;交换两人手上拥有的硬币数量&#xff0c;或什么都不做 …

JS逆向实战案例2——某房地产token RSA加密

说明&#xff1a;仅供学习使用&#xff0c;请勿用于非法用途&#xff0c;若有侵权&#xff0c;请联系博主删除 作者&#xff1a;zhu6201976 一、 反爬分析 url1&#xff1a;aHR0cDovL3pmY2ouZ3ouZ292LmNuL3pmY2ovZnl4eC94a2I/c1Byb2plY3RJZD05MzBlMDQ0MmJjNjA0MTBkYTgzNzQ0MmQ…

用可视化案例讲Rust编程2. 编码的核心组成:函数

从第一天学习编程&#xff0c;可能大家就听说这样的组成公式&#xff1a; 程序算法数据结构 ——该公式出自著名计算机科学家沃思(Nikiklaus Wirth) 实际上&#xff0c;程序除了以上两个主要要素之外&#xff0c;还应当采用结构化程序设计方法进行程序设计&#xff0c;并且用…

SpringBoot多环境配置Maven Profile组

Maven profile组 注意切换配置时 mvn clean下 或者 clean 加install 或者compile 编译 clean之后 install下 或者compile 编译 nohup java -Xms256m -Xmx512m -Dfile.encodingUTF-8 -jar demo.jar --spring.profiles.activeprod > system.log 2>&1 &

k8s中的基础概念

k8s可以从硬件和软件两方面来理解&#xff1a; 硬件&#xff1a; 1、节点&#xff08;Node&#xff09;&#xff1a;类似于手机、平板、电脑 2、集群&#xff08;Cluster&#xff09;&#xff1a;多个节点组合到一起 3、持久卷&#xff08;Persistent Volumes&#xff09;&…

SpringCloud 之HttpClient、HttpURLConnection、OkHttpClient切换源码

承接上文&#xff0c;之前已经分析过OpenFegin 的创建、发送请求源码了&#xff0c;接下来&#xff0c;分析下底层的HttpClient、HttpURLConnection、OkHttpClient切换从源码级别来看是如何做到的。 Spring Cloud OpenFegin&#xff08;创建、发送请求&#xff09;源码 Http…

在本地测试nginx中localhost不行,需要写成127.0.0.1

在Windows 10系统的命令提示符cmd中&#xff0c;执行命令ping localhost&#xff0c;并没有出现我与其的ip地址“127.0.0.1”&#xff0c;而是“[::1]”。 问题原因 在cmd中ping localhost解析出来的是ipv6的::1的原因是windows有个优先解析列表&#xff0c;当ipv6的优先级高于…

深度学习目标跟踪简述

深度学习目标跟踪是一个活跃的研究领域&#xff0c;它涉及使用深度学习技术来跟踪视频或实时摄像头中的对象。这个领域通常包括以下几个关键方面&#xff1a; 目标检测&#xff1a;在开始跟踪前&#xff0c;首先需要在视频的初始帧中检测到目标。这通常是通过卷积神经网络&…

基于ssm物流配送人员车辆调度管理系统的设计与实现+vue论文

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统物流配送人员车辆调度信息管理难度大&#xff0c;容错率低…

Thingsbaord采用redis缓存(自用)

在CentOS系统上&#xff0c;您可以通过以下步骤使用yum安装Redis&#xff1a; 添加EPEL仓库&#xff1a; 首先&#xff0c;需要添加EPEL&#xff08;Extra Packages for Enterprise Linux&#xff09;仓库&#xff0c;因为Redis可能不在默认的CentOS仓库中。使用以下命令添加EP…