Redis 核心技术与实战
蒋德钧
中科院计算所副研究员
81696 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 53 讲
开篇词 (1讲)
实践篇 (28讲)
Redis 核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

20 | 删除数据后,为什么内存占用率还是很高?

jemalloc的分配策略
控制碎片清理的参数
基本机制
外因:键值对大小不一样和删改操作
内因:内存分配器的分配策略
自动内存碎片清理
重启Redis实例
mem_fragmentation_ratio
INFO命令
内存碎片是如何形成的?
内存碎片的成因
内存空间闲置
内存碎片自动清理
重视内存碎片
了解内存碎片
如何清理内存碎片?
如何判断是否有内存碎片?
什么是内存碎片?
每课一问
小结
内存碎片
删除数据后,为什么内存占用率还是很高?

该思维导图由 AI 生成,仅供参考

你好,我是蒋德钧。
在使用 Redis 时,我们经常会遇到这样一个问题:明明做了数据删除,数据量已经不大了,为什么使用 top 命令查看时,还会发现 Redis 占用了很多内存呢?
实际上,这是因为,当数据删除后,Redis 释放的内存空间会由内存分配器管理,并不会立即返回给操作系统。所以,操作系统仍然会记录着给 Redis 分配了大量内存。
但是,这往往会伴随一个潜在的风险点:Redis 释放的内存空间可能并不是连续的,那么,这些不连续的内存空间很有可能处于一种闲置的状态。这就会导致一个问题:虽然有空闲空间,Redis 却无法用来保存数据,不仅会减少 Redis 能够实际保存的数据量,还会降低 Redis 运行机器的成本回报率。
打个形象的比喻。我们可以把 Redis 的内存空间比作高铁上的车厢座位数。如果高铁的车厢座位数很多,但运送的乘客数很少,那么,高铁运行一次的效率低,成本高,性价比就会降低,Redis 也是一样。如果你正好租用了一台 16GB 内存的云主机运行 Redis,但是却只保存了 8GB 的数据,那么,你租用这台云主机的成本回报率也会降低一半,这个结果肯定不是你想要的。
所以,这节课,我就和你聊聊 Redis 的内存空间存储效率问题,探索一下,为什么数据已经删除了,但内存却闲置着没有用,以及相应的解决方案。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Redis内存碎片问题及解决方案 Redis在删除数据后,内存占用率依然很高的问题,主要是由于内存分配器的分配策略和Redis的负载特征所导致的内存碎片问题。内存碎片是指操作系统剩余内存空间中没有大小为N字节的连续空间,造成内存空间的不连续。内存分配器的固定大小分配策略以及Redis中不同大小的键值对和删改操作都会导致内存碎片的形成。内存碎片的存在会降低Redis的内存实际利用率,影响Redis的运行效率。为了解决这一问题,可以通过使用Redis的INFO命令来查询内存使用情况,进而判断是否存在内存碎片。针对内存碎片问题,可以采取相应的解决方案,以提高Redis的内存空间存储效率,增加存储的数据量。 文章还介绍了如何清理内存碎片以及Redis自身提供的内存碎片自动清理的方法。内存碎片清理的基本机制是“搬家让位,合并空间”,通过数据拷贝和释放原有空间来合并不连续的内存空间。然而,碎片清理会带来时间开销和性能影响,因此Redis提供了自动内存碎片清理机制,通过设置参数来控制清理的时机和CPU占用比例,以减少对Redis性能的影响。 总的来说,Redis内存碎片问题是一个需要重视的技术挑战,但通过合理的监控和自动清理机制,可以有效地提升Redis的内存空间存储效率,从而提高系统性能和稳定性。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Redis 核心技术与实战》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(54)

  • 最新
  • 精选
  • Kaito
    如果 mem_fragmentation_ratio 小于 1 了,Redis 的内存使用是什么情况呢?会对 Redis 的性能和内存空间利用率造成什么影响? mem_fragmentation_ratio小于1,说明used_memory_rss小于了used_memory,这意味着操作系统分配给Redis进程的物理内存,要小于Redis实际存储数据的内存,也就是说Redis没有足够的物理内存可以使用了,这会导致Redis一部分内存数据会被换到Swap中,之后当Redis访问Swap中的数据时,延迟会变大,性能下降。 通过这篇文章了解到,Redis在进行内存碎片整理时,由于是主线程操作的,所以这块也是一个影响Redis性能的风险点。 其中active-defrag-ignore-bytes和active-defrag-threshold-lower参数主要用于控制达到什么阈值后开始碎片整理,如果配置的碎片大小和碎片率在可接受的范围内,那么Redis不会进行碎片整理,也就不会对Redis产生性能影响。 而达到设定阈值开始碎片整理后,active-defrag-cycle-min和active-defrag-cycle-max参数则用来控制在这期间,Redis主线程资源使用的上下限,这个需要根据碎片整理的时间、Redis的响应延迟进行权衡,合理配置。 我个人认为,应该优先保证Redis性能尽量不受影响,让碎片整理期间的资源消耗控制在稳定的范围内,并尽量缩短碎片整理的时间。
    2020-09-23
    16
    296
  • test
    mem_fragmentation_ratio小于1,说明redis内存不够用了,换了一部分到swap中,会严重影响性能。
    2020-09-23
    40
  • Geek_b8d5c9
    有点想Java中的垃圾回收算法的标记整理
    2020-12-11
    21
  • escray
    数据删除后,Redis 释放的内存空间由内存分配器管理,不会立刻返回给操作系统。 再加上内存碎片的问题,感觉是因为 Redis 是使用 C 语言实现的,如果是在 JVM 上,内存管理就不会成为棘手的问题了,当然性能上 JVM 比起 C 语言来还是有不少劣势。 其实 Redis 清理内存碎片的方式和 JVM 的内存管理也很类似。 active-defrag-ignore-bytes、active-defrag-threshold-lower、active-defrag-cycle-min、active-defrag-cycle-max 是 4 个和 Redis 内存碎片清理机制有关的参数,而 100mb、10、25、75 应该是老师给出的参考值或者是最佳实践吧。 如果 mem_fragmentation_ratio 小于 1,那么我来猜测一下,如果小于 0.5 感觉内存的利用率比较低,内存的 ROI 太低,可以考虑减少给 Redis 分配的内存;而在 0.5 ~ 1 之间的话,感觉应该是比较合适的,但是也有可能会有太多的碎片需要整理。 看了课代表的回答,惭愧的发现,我完全搞反了 used_memory_rss 和 used_memory 的含义,其中 rss 表示 resident set size used_memory: Total number of bytes allocated by Redis using its allocator (either standard libc, jemalloc, or an alternative allocator such as tcmalloc) used_memory_rss: Number of bytes that Redis allocated as seen by the operation system (a.k.a resident set size). Ideally, the used_memory_rss value should be only slightly higher than used_momory. When rss >> used, a large difference means there is memory fragmentation... When used >> rss, it means part of Redis memory has been swapped off by the operating system: expect some significant latencies. 在留言里没有看到老师的身影(“作者回复”),爱总结的非凡哥也不见了,只有课代表还在。
    2021-03-27
    1
    16
  • 树斌
    实际案例,redis-cluster三主三从,检查所有节点的内存碎片率均小于1,在0.7-0.9之间,used_memory基本每个节点都只有12m左右,但是检查swap确认是没有虚拟内存交换的,不知道这种情况作何解释?一直没闹明白
    2020-09-24
    4
    15
  • IT小僧
    小于1不一定是发生了swap 也有可能是因为内存空白页导致的,前者会影响性能,后者不会。
    2020-12-15
    4
    14
  • 悟空聊架构
    课后问题: 如果 mem_fragmentation_ratio 小于 1 了,Redis 的内存使用是什么情况呢?会对 Redis 的性能和内存空间利用率造成什么影响呢? mem_fragmentation_ratio = used_memory_rss / used_memory < 1 , 说明操作系统分配给Redis进程的物理内存 < Redis实际存储数据的内存。 原因和影响: 1.Redis 没有申请到足够的物理内存 2.Redis 的一部分内存数据会被换到 Swap 中 3.Redis访问 swap 中的数据时,相当于与磁盘进行交互,访问慢,性能下降。 swap 是什么? 内存 swap 是操作系统里将内存数据在内存和磁盘间来回换入和换出的机制,涉及到磁盘的读写。一旦出发 swap,性能会收到慢速磁盘读写的影响。 Redis 实例自身使用了大量的内存,导致物理机器的可用内存不足。 和 Redis 实例在同一台机器上运行的其他进程,在进行大量的文件读写操作,文件读写本身会占用系统,导致分配给 Redis 实例的内存量变少,进而出发 Redis 发生 swap。 如何识别和处理 Redis 内存碎片 info memory 命令是一个好工具,可以帮助你查看碎片率的情况; INFO memory 碎片率阈值是一个好经验,可以帮忙你有效地判断是否要进行碎片清理了; mem_fragmentation_ratio = used_memory_rss/ used_memory used_memory_rss 是操作系统实际分配给 Redis 的物理内存空间,里面就包含了碎片; used_memory 是 Redis 为了保存数据实际申请使用的空间 内存碎片自动清理是一个好方法,可以避免因为碎片导致 Redis 的内存实际利用率降低,提升成本收益率。 config set activedefrag yes active-defrag-ignore-bytes 100mb:表示内存碎片的字节数达到 100MB 时,开始清理; ​active-defrag-threshold-lower 10:表示内存碎片空间占操作系统分配给 Redis 的总空间比例达到 10% 时,开始清理。(第一个和第二个需要同时满足才会开始清理) active-defrag-cycle-min 25: 表示自动清理过程所用 CPU 时间的比例不低于 25%,保证清理能正常开展; active-defrag-cycle-max 75:表示自动清理过程所用 CPU 时间的比例不高于 75%,一旦超过,就停止清理,从而避免在清理时,大量的内存拷贝阻塞 Redis,导致响应延迟升高。
    2021-05-29
    1
    11
  • 数学汤家凤
    内存分配向上取整导致的内部碎片 内存反复分配回收导致的外部碎片 解决方法移动,什么时候移动?碎片太多且CPU不忙时移动
    2020-11-11
    1
    6
  • 小西几
    启用碎片整理的时候报错 127.0.0.1:6379> CONFIG SET activedefrag yes (error) DISABLED Active defragmentation cannot be enabled: it requires a Redis server compiled with a modified Jemalloc like the one shipped by default with the Redis source distribution 此时碎片率已经达到4.28,并且redis 还没有启用持久化, 其他数据: used_memory:3304902272 used_memory_human:3.08G used_memory_rss:14155644928 used_memory_rss_human:13.18G used_memory_peak:5176474576 used_memory_peak_human:4.82G 请问老师,我该怎么执行碎片整理。这是生产环境,比较重要。因为内存马上不够用了。
    2020-09-27
    12
    6
  • 日落黄昏下
    刚建的redis实例的内存碎片率一般会小于1,这个时候并没有数据占用内存,但是会创建复制积压缓冲区,由于此时并没有使用,操作系统并没有真正把内存分配给redis而redis是有记录这个内存的,所以造成了内存碎片率小于1
    2021-10-11
    4
收起评论
显示
设置
留言
54
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部