当前位置: 首页 > news >正文

Redis内存碎片

什么是内存碎片?

你可以将内存碎片简单地理解为那些不可用的空闲内存。

举个例子:操作系统为你分配了 32 字节的连续内存空间,而你存储数据实际只需要使用 24 字节内存空间,那这多余出来的 8 字节内存空间如果后续没办法再被分配存储其他数据的话,就可以被称为内存碎片

Redis 内存碎片虽然不会影响 Redis 性能,但是会增加内存消耗。

为什么会有 Redis 内存碎片?

Redis 内存碎片产生比较常见的 2 个原因:

1、Redis 存储数据的时候向操作系统申请的内存空间可能会大于数据实际需要的存储空间。

以下是这段 Redis 官方的原话:

To store user keys, Redis allocates at most as much memory as the maxmemory setting enables (however there are small extra allocations possible).

Redis 使用 zmalloc 方法(Redis 自己实现的内存分配方法)进行内存分配的时候,除了要分配 size 大小的内存之外,还会多分配 PREFIX_SIZE 大小的内存。

zmalloc 方法源码如下(源码地址:https://github.com/antirez/redis-tools/blob/master/zmalloc.c):

另外,Redis 可以使用多种内存分配器来分配内存

void *zmalloc(size_t size) {// 分配指定大小的内存void *ptr = malloc(size+PREFIX_SIZE);if (!ptr) zmalloc_oom_handler(size);
#ifdef HAVE_MALLOC_SIZEupdate_zmalloc_stat_alloc(zmalloc_size(ptr));return ptr;
#else*((size_t*)ptr) = size;update_zmalloc_stat_alloc(size+PREFIX_SIZE);return (char*)ptr+PREFIX_SIZE;
#endif
}

( libc、jemalloc、tcmalloc),默认使用 jemalloc,而 jemalloc 按照一系列固定的大小(8 字节、16 字节、32 字节……)来分配内存的。jemalloc 划分的内存单元如下图所示:

当程序申请的内存最接近某个固定值时,jemalloc 会给它分配相应大小的空间,就比如说程序需要申请 17 字节的内存,jemalloc 会直接给它分配 32 字节的内存,这样会导致有 15 字节内存的浪费。不过,jemalloc 专门针对内存碎片问题做了优化,一般不会存在过度碎片化的问题。

2、频繁修改 Redis 中的数据也会产生内存碎片。

当 Redis 中的某个数据删除时,Redis 通常不会轻易释放内存给操作系统。

这个在 Redis 官方文档中也有对应的原话:

文档地址:Memory optimization | Docs 

如何查看 Redis 内存碎片的信息?

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

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 集群的话,你可以将碎片率过高的主节点转换为从节点,以便进行安全重启。

http://www.lryc.cn/news/516839.html

相关文章:

  • Express 加 sqlite3 写一个简单博客
  • 正则表达式进阶学习(一):环视、捕获分组与后向引用
  • 《Vue3 七》插槽 Slot
  • 【C++数据结构——线性表】顺序表的基本运算(头歌实践教学平台习题)【合集】
  • Linux C/C++编程-获得套接字地址、主机名称和主机信息
  • USB kbtab linux 驱动代码
  • 力扣 跳跃游戏
  • 使用npm 插件[mmdc]将.mmd时序图转换为图片
  • ffmpeg 常用命令
  • 从入门到实战:C 语言 strlen 函数通关指南
  • npm install --global windows-build-tools --save 失败
  • 十种基础排序算法(C语言实现,带源码)(有具体排序例子,适合学习理解)
  • 基于fMRI数据计算脑脊液(CSF)与全脑BOLD信号的时间耦合分析
  • 实现websocket心跳检测,断线重连机制
  • ComfyUI节点安装笔记
  • 深度学习,训练集准确率高,但验证集准确率一直不上升,很低的问题
  • 【C语言程序设计——选择结构程序设计】求输入的日期是该年的第几天(头歌实践教学平台习题)【合集】
  • Lumos学习王佩丰Excel二十四讲系列完结
  • 前后端规约
  • 【数据可视化】数据可视化看板需求梳理模板(含示例)
  • CArray原理是什么,通过示例来展示如何使用?
  • 更换WordPress主题的基础知识及注意事项
  • springcloud篇3-docker需熟练掌握的知识点
  • 基于单片机的直流稳压电源的设计(论文+源码)
  • uniapp-vue3 实现, 一款带有丝滑动画效果的单选框组件,支持微信小程序、H5等多端
  • 解锁 C 语言字符函数密码,开启高效编程之路
  • LLM之RAG实战(五十一)| 使用python和Cypher解析PDF数据,并加载到Neo4j数据库
  • 力扣-数组-01两数之和
  • Flutter中的网络请求图片存储为缓存,与定制删除本地缓存
  • 保障移动应用安全:多层次安全策略应对新兴威胁