Redis 如何解决内存占用过大、不释放的问题

news2024/11/15 8:30:17

错误日志

通过 redis.log 可以看到错误日志如下:Cannot allocate memory

15602:M 30 Dec 2022 17:39:09.988 * RDB memory usage when created 19775.56 Mb
15602:M 30 Dec 2022 17:39:44.766 # Done loading RDB, keys loaded: 529954, keys expired: 26.
15602:M 30 Dec 2022 17:39:44.766 * DB loaded from disk: 34.780 seconds
15602:M 30 Dec 2022 17:39:44.766 * Ready to accept connections
15602:M 30 Dec 2022 17:41:40.133 * 10000 changes in 60 seconds. Saving...
15602:M 30 Dec 2022 17:41:40.184 # Can't save in background: fork: Cannot allocate memory
15602:M 30 Dec 2022 17:41:46.015 * 10000 changes in 60 seconds. Saving...
15602:M 30 Dec 2022 17:41:46.070 # Can't save in background: fork: Cannot allocate memory
15602:M 30 Dec 2022 17:41:52.019 * 10000 changes in 60 seconds. Saving...

内存淘汰机制

过期数据的删除策略

如果假设你设置了一批 key 只能存活 1 分钟,那么 1 分钟后,redis 是怎么对这批 key 进行删除的呢?

常用的过期数据的删除策略就两个(重要!自己造缓存轮子的时候需要格外考虑的东西):

  • 惰性删除 :只会在取出 key 的时候才对数据进行过期检查。这样对 CPU 最友好,但是可能会造成太多过期 key 没有被删除。
  • 定期删除 : 每隔一段时间抽取一批 key 执行删除过期 key 操作。并且,redis 底层会通过限制删除操作执行的时长和频率来减少删除操作对 CPU 时间的影响。

定期删除对内存更加友好,惰性删除对 CPU 更加友好。两者各有千秋,所以 redis 采用的是 定期删除+惰性/懒汉式删除

但是,仅仅通过给 key 设置过期时间还是有问题的。因为还是可能存在定期删除和惰性删除漏掉了很多过期 key 的情况。 这样就导致大量过期 key 堆积在内存里,然后就 Out of memory 了。

怎么解决这个问题呢?答案就是:redis 内存淘汰机制。

redis 内存淘汰机制

使用 config get maxmemory-policy 命令,来查看当前 Redis 的内存淘汰策略。

Redis 默认使用的是 noeviction 类型的内存淘汰机制,它表示当运行内存超过最大设置内存时,不淘汰任何数据,但新增操作会报错!!!!

redis 提供 6 种数据淘汰策略:

  • volatile-lru(least recently used):从已设置过期时间的数据集(server.db[i].expires)中挑选最近 最少使用的数据淘汰
  • volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
  • volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
  • allkeys-lru(least recently used):当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key
  • allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
  • no-eviction:禁止驱逐数据,也就是说当内存不足以容纳新写入数据时,新写入操作会报错。这个应该没人使用吧!

4.0 版本后增加以下两种:

  • volatile-lfu(least frequently used):从已设置过期时间的数据集(server.db[i].expires)中挑选最不经常使用的数据淘汰
  • allkeys-lfu(least frequently used):当内存不足以容纳新写入数据时,在键空间中,移除最不经常使用的 key

如何配置

修改 redis.conf 文件,进行内存淘汰策略的配置
在这里插入图片描述

内存碎片率

如何查看内存碎片率

使用 info memory 命令即可查看 Redis 内存相关的信息。下图中每个参数具体的含义,Redis 官方文档有详细的介绍:https://redis.io/commands/INFO 。

Redis 内存碎片率的计算公式:mem_fragmentation_ratio (内存碎片率)= used_memory_rss (操作系统实际分配给 Redis 的物理内存空间大小) / used_memory(Redis 内存分配器为了存储数据实际申请使用的内存空间大小)

也就是说,mem_fragmentation_ratio (内存碎片率)的值越大代表内存碎片率越严重。

一定不要误认为used_memory_rss 减去 used_memory 值就是内存碎片的大小!!!这不仅包括内存碎片,还包括其他进程开销,以及共享库、堆栈等的开销。

很多小伙伴可能要问了:“多大的内存碎片率才是需要清理呢?”。

通常情况下,我们认为 mem_fragmentation_ratio > 1.5 的话才需要清理内存碎片。 mem_fragmentation_ratio > 1.5 意味着你使用 Redis 存储实际大小 2G 的数据需要使用大于 3G 的内存。

如果想要快速查看内存碎片率的话,你还可以通过下面这个命令:

redis-cli -p 6379 info | grep mem_fragmentation_ratio

另外,内存碎片率可能存在小于 1 的情况。这种情况我在日常使用中还没有遇到过,感兴趣的小伙伴可以看看这篇文章 故障分析 | Redis 内存碎片率太低该怎么办?- 爱可生开源社区 。

如何清理 Redis 内存碎片

Redis4.0-RC3 版本以后自带了内存整理,可以避免内存碎片率过大的问题。

直接通过 config set 命令将 activedefrag 配置项设置为 yes 即可。

config set activedefrag yes

具体什么时候清理需要通过下面两个参数控制:

# 内存碎片占用空间达到 500mb 的时候开始清理
config set active-defrag-ignore-bytes 500mb

# 内存碎片率大于 1.5 的时候开始清理
config set active-defrag-threshold-lower 50

通过 Redis 自动内存碎片清理机制可能会对 Redis 的性能产生影响,我们可以通过下面两个参数来减少对 Redis 性能的影响:

# 内存碎片清理所占用 CPU 时间的比例不低于 20%
config set active-defrag-cycle-min 20

# 内存碎片清理所占用 CPU 时间的比例不高于 50%
config set active-defrag-cycle-max 50

另外,重启节点可以做到内存碎片重新整理。如果你采用的是高可用架构的 Redis 集群的话,你可以将碎片率过高的主节点转换为从节点,以便进行安全重启。

参考:JavaGuide 关于 Cache 的整理

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

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

相关文章

基于长短期记忆网络和凸优化算法的综合智能电网的可再生能源预测(Python代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

string(四)————底层实现

目录 引言 外层包装 成员变量设计 接口实现 引言 在之前的博客中我简单介绍了string的相关使用方法和接口,现在我们自己来模拟实现一下它的底层(注:不同编译器底层实现不同,这里只是其中一种的实现)。 外层包装 …

Allegro如何在PCB上查看焊盘信息操作指导

Allegro如何在PCB上查看焊盘信息操作指导 在做PCB设计的时候需要查看焊盘的信息,Allegro上支持直接在PCB上查看焊盘的信息,如下图 具体操作如下 选择Tools-Pad stack选择Modify Design Padstack

【漏洞复现】Django SQL注入漏洞 (CVE-2022-28346)

文章目录一、简介二、漏洞概述三、漏洞影响版本四、漏洞分析五、漏洞复现六、修复方法一、简介 Django是用Python开发的一个免费开源的Web结构,几乎包括了Web使用方方面面,能够用于快速建立高性能、文雅的网站,Diango提供了许多网站后台开发…

pcl 姿态变换 之 旋转平移

一、简介 最近在做一个点云的项目,姿态的变换是一个很重要的环节,从数学上需要彻底理解这些东西之前一直在使用,但是没有系统的总结过,接着2023年元旦的三天时间好好学习一下,然后在同事面前说自己是数学系的很丢人啊…

【MySQL进阶】从计算机层面看索引凭什么让查询效率提高这么多?

【MySQL进阶】从计算机层面看索引凭什么让查询效率提高这么多? 文章目录【MySQL进阶】从计算机层面看索引凭什么让查询效率提高这么多?磁盘IO和预读:索引是什么?BTree索引BTree索引让我们先来了解一下计算机的数据加载。磁盘IO和预…

中国为印尼建设的高铁顺利推进,印度网友与日本网友就高铁互怼

日前中国为印尼建设的雅万高铁已开始进行试运行测试,预计将在明年6月正式运行,与雅万高铁差不多时间开始的日本为印度孟买建设的高铁项目才建设了15公里,为此印度网友和日本网友对中日高铁技术的差距展开了争论。2011年日本相关机构开始对印尼…

羊的第四天,开始这篇年终总结

比较尴尬,从今年“羊”到明年,所以这篇文章也是每天抽出一点时间写写,可能会比较乱,先大致分下核心内容吧:今年总结新年展望今年总结先是完成了《数字硬件建模系列的Verilog篇》,效果不好不坏,主…

算法设计与分析复习03:动态规划算法

算法设计与分析复习03:动态规划算法 文章目录算法设计与分析复习03:动态规划算法复习重点动态规划算法斐波那契数列及其应用矩阵链乘法凸多边形剖分矩阵链乘法凸多边形剖分最长公共子序列最大子段和(字数组)0-1背包编辑距离钢条切…

pycharm-qt5-designer1

pycharm-qt5-designer1一: designer界面介绍1. 新建模板二: 控件箱简介1. Layouts 布局2. Spacers 间隔(透明)3. Button4. Item views5. Item Widgets 条目控件6. Containers 容器7. input Widgets 输入控件8. Display Widgets 显示控件三: 控件属性简介1. sizePolicy: 控件大小…

gitlab-ci.yml关键字(四)allow_failure 、artifacts 、cache

allow_failure 我们知道,流水线作业在运行时如果失败了,就会停止运行,但allow_failure可以让我们自由的控制当前作业失败时,是否还需要继续运行。 要让管道继续运行后续作业,请使用allow_failure: true要停止管道运行…

OASIS协议标准文档的解读_第一部分

译者注: 利用2022年圣诞假期,终于解读完OASIS标准协议的文档。本翻译文档基于SEMI 草案标准 3626 (2003/04/23). 因为SEMI的原版标准草案涉及到版权的一些问题,并不是公开的。因此我并不是原文原样翻译,会加入很多我自己的理解和…

cnpm : 无法将“cnpm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。

从报错来看明显是没有装 cnpm 检查本地是否安装了cnpm包管理工具 命令:npm list --depth0 -global 查看一下电脑是否安装了cnpm 如果已经安装了,那么会有如下图所示的内容: 从以上来看确实是没有装 则需要安装镜像,执行命令为…

Vue3详细讲解

Vue 3 介绍 文章目录Vue 3 介绍为什么要学习 vue 3Vue3 动机 和 新特性Vite 的使用vite介绍为什么选 Vite ?Vite 的基本使用Vue3.0项目介绍vscode插件说明组合式APIcomposition API vs options API体验 composition APIsetup 函数reactive 函数ref 函数script setup…

【云原生 | Kubernetes 实战】19、K8s Ingress-Controller 高可用方案

目录 一、Ingress 和 Ingress Controller 概述 1.1 回顾下 service 四层代理 1.2 Ingress 介绍 1.3 Ingress Controller 介绍 1.4 Ingress 和 Ingress Controller 总结 1.5 使用 Ingress Controller 代理 k8s 内部 pod 的流程 二、创建两个 ingress-controller 高可用…

凌云驭势 亚马逊云科技开启re:Invent中国行

‍‍数据智能产业创新服务媒体——聚焦数智 改变商业近日,亚马逊云科技召开了2022 re:Invent全球大会。作为云计算的开创者,每年亚马逊云科技举办的re:Invent全球大会都会成为产业的风向标,备受业内人士关注。2022年,面对全球数字…

【STL学习之路】vector的模拟实现

文章目录一、接口总览二、vector成员变量三、默认成员函数构造函数① -- 默认无参构造构造函数② -- 迭代器区间构造构造函数③ -- n个val构造拷贝构造函数赋值运算符重载析构函数四、迭代器六、容量以及元素访问的相关接口emptysize和capacityreserveresize七、增删查改等接口…

async await 的基础使用和实现原理

async await 使用基础原理 async/await用法 其实你要实现一个东西之前,最好是先搞清楚这两样东西 这个东西有什么用? 这个东西是怎么用的? 有什么用? async/await的用处就是:用同步方式,执行异步操作&…

商会机构源码模板系统包含了信息管理、新闻管理、广告管理、系统管理等功能 v3.9

内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示三、学习资料下载一、详细介绍 XYCMS商会机构源码模板系统是以aspaccess进行开发的商会网站源码,包含了信息管理、新闻管理、广告管理、系统管理等功能。 XYCMS商会机构源码模板系统功能简述: 商…

大数据面试题Spark篇(1)

1.spark数据倾斜 数据倾斜俩大直接致命后果:Out Of Memory,运行速度慢。这主要是发生在Shuffle阶段。同样Key的数据条数太多了。导致了某个key所在的Task数据量太大了,远远超过其他Task所处理的数据量。 数据倾斜一般会发生在shuffle过程中…