Redis内存碎片:深度解析与优化策略

这篇具有很好参考价值的文章主要介绍了Redis内存碎片:深度解析与优化策略。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文已收录至GitHub,推荐阅读 👉 Java随想录

微信公众号:Java随想录

原创不易,注重版权。转载请注明原作者和原文链接

目录
  • 内存碎片如何产生的
  • 内存分配器
  • 怎么看是否有内存碎片
  • 碎片率的意义
  • 清理内存碎片
    • 低于4.0-RC3版本的Redis
    • 高于4.0-RC3版本的Redis

在我们探究和优化Redis性能的过程中,「Redis内存碎片」是一个不可忽视的话题。

这篇文章将深入研究这个看似微不足道,但实际上对Redis运行效率产生重要影响的问题。首先,让我们揭开Redis内存碎片的神秘面纱,理解它的本质及其为何成为我们必须面对的挑战。

内存碎片如何产生的

Redis内存碎片主要是因为Redis数据存储和回收过程中的内存管理问题导致的。

Redis分配内存时,会根据需要申请一段连续的内存空间。但当Redis删除或修改数据时,释放的内存空间并不一定能被立即重新利用,尤其是当这些空闲内存空间大小不一致时,就可能导致内存碎片的出现。

为了提高内存使用的效率,Redis内部使用内存分配器来对内存的申请和释放进行管理。Redis使用的内存分配器默认是「jemalloc」。

而内存分配器是按照固定大小来分配内存的,并不是完全按照程序申请的内存大小来进行分配。

比如程序申请一个20字节的内存,内存分配器会分配一个32字节的内存空间,这么做是为了减少分配次数。redis会申请不同大小的内存空间来存储不同业务不同类型的数据,由于内存按照固定大小分配且会比实际申请的内存要大一些,这个过程中会产生内存碎片。

举个生活中的例子,帮助大家理解:

假设你正在整理一间图书馆。图书馆的书架就像是Redis储存数据的内存空间。每本书都代表不同大小的数据。刚开始时,你把所有的书都按照大小放好。小书在一侧,大书在另一侧。这样你可以有效地利用书架的空间,也方便找书。

但是,如果你需要移除一些书(删除某些数据),然后又加入新的书(新增数据),就可能出现问题了。例如,你移除了一些大书,把它们的位置空出来,然后把新的小书放进去。这样下来,原本属于大书的空间,现在只被小书部分占用,剩余的空白就成了“内存碎片”。

又或者你有一堆新的大书要放,但书架上只有分散的小书的空位,无法容纳这些大书。这个时候你可能需要重新排列整个书架(类似于Redis的内存整理)去腾出连续的大片空间来摆放这些新的大书。

总结来说:当数据不断删除和新增时,内存中空出的位置可能无法完全匹配新数据的大小,导致产生未被利用的“碎片”空间,这就是内存碎片。

内存分配器

Redis 使用内存分配器来管理其在运行期间需要使用的内存资源。可以是libc、jemalloc、tcmalloc。默认是jemalloc。

要指定 Redis 使用哪个内存分配器,你需要在编译 Redis 时做出选择。通常在执行 make 命令时可以通过 MALLOC 参数来指定。例如,如果你想使用 jemalloc,你可以像这样编译 Redis:make MALLOC=jemalloc

jemalloc在64位系统中,将内存空间划分为小、大、巨大三个范围。每个范围内又划分了许多小的内存块单位,存储数据的时候,会选择大小最合适的内存块进行存储。

jemalloc划分的内存单元如下图所示:

也就是说Redis是以指定大小的块为单位进行连续内存分配的,而不是按需分配的,Redis 会根据申请的内存最接近的固定值分配相应大小的空间。

这就像你有不同的箱子,为了装东西,你需要找一个体积最接近的箱子来装。但是装进去后,你发现还有空间可以放一些小东西,就无需再找箱子了。

但是,这种分配空间的方式会带来一定程度的内存碎片。我们可以把固定大小的划分空间看成不同体积的箱子,每种箱子里的空间不同程度上都会有剩余。这些剩余的空间就是内存碎片。

怎么看是否有内存碎片

我们登陆到Redis服务器上,执行以下命令,这会返回一段描述Redis内存使用情况的文本。

redis> info memory

我们会看到类似如下的信息:

在这里,我们主要关注的是名为mem_fragmentation_ratio的字段,它显示了Redis内存碎片的比例。

如果mem_fragmentation_ratio大于1,那就表示存在内存碎片。这个值越大,内存碎片就越多。如果该值非常接近1或者小于1,则表示内存碎片很少或者没有。

计算公式为:

mem_fragmentation_ratio = used_memory_rss / used_memory

其中:

  • used_memory_rss:代表Redis进程占用的总物理内存大小(包括码区、数据区和堆栈等),单位是字节。
  • used_memory:代表Redis分配器申请的内存总量,也就是从操作系统角度看进程实际使用的虚拟内存空间,单位是字节。

碎片率的意义

mem_fragmentation_ratio的不同值,说明不同的情况。

  • 大于1:说明内存有碎片,通常在1到1.5之间是正常的。
  • 大于1.5:说明内存碎片率比较大,需要考虑是否要进行内存碎片清理,要引起重视。
  • 小于1:说明已经开始使用交换内存,也就是使用硬盘了,正常的内存不够用了,需要考虑是否要进行内存的扩容,使用swap是相当影响性能的。

清理内存碎片

低于4.0-RC3版本的Redis

Redis 4.0-RC3之前的版本并没有内置的内存碎片整理工具。如果你想要清理内存碎片,可以通过重启的方式。

当Redis重新启动时,它会通过RDB持久化功能将数据存储到磁盘,然后再从磁盘加载数据到内存,这个过程可以有效地清理内存碎片。但这种方法会导致服务的临时中断。

高于4.0-RC3版本的Redis

Redis4.0-RC3版本开始,引入了active-defrag 特性。可以在不重启的情况下,自动进行碎片清理。

开启配置如下,此选项的默认值是关闭的,激活碎片整理可能会占据一些 CPU 时间。

redis> config set activedefrag yes 

注意:自动清理内存碎片的功能需要该Redis的内存分配器是jemalloc时才能启用

启用后需要同时满足下面2个参数的设置条件时才会触发自动清理

active-defrag-ignore-bytes 100mb    # 默认100MB,表示内存碎片空间达到100MB时
active-defrag-threshold-lower 10    # 默认10,表示内存碎片空间占OS分配给redis的物理内存空间的比例达到10%时

redis是单进程模型,内存碎片自动清理是通过主线程操作的,也会消耗一定的CPU资源。为了避免自动清理降低Redis的处理性能,如下两个参数可以控制清理动作消耗的CPU时间比例的上下限:

active-defrag-cycle-min 5  # 默认5,表示自动清理过程所用 CPU 时间的比例不低于5%,保证清理能正常开展;
active-defrag-cycle-max 75 # 默认75,表示自动清理过程所用 CPU 时间的比例不高于 75%,一旦超过,就停止清理,从而避免在清理时,大量的内存拷贝阻塞 Redis,导致响应延迟升高。

如果你对自动清理的效果不满意,可以使用如下命令,直接进行手动碎片清理:

redis > memory purge

需要注意的是,该命令会阻塞主进程,并且目前也仅实现了jemalloc作为内存分配器的内存统计,对其他分配器暂不支持。

本篇文章到这就结束了。在我们深入研究Redis内存碎片管理和优化策略后,可以明确一点:理解并合理处理内存碎片化对于保证Redis的性能及稳定性至关重要。

不论是进行内存分配策略的调整,还是使用适当的数据结构,都是对Redis内存管理的优化。

同时,定期的监控和审视也是必不可少的步骤。希望本文能为你在处理Redis内存碎片问题上提供一些有价值的启示。记住,每一个优秀的工程师都应该以理解其使用的工具为荣。让我们持续关注和优化Redis,使其更好地服务于我们的项目,推动业务的发展。


感谢阅读,如果本篇文章有任何错误和建议,欢迎给我留言指正。

老铁们,关注我的微信公众号「Java 随想录」,专注分享Java技术干货,文章持续更新,可以关注公众号第一时间阅读。文章来源地址https://www.toymoban.com/news/detail-712103.html

到了这里,关于Redis内存碎片:深度解析与优化策略的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深度解析Elasticsearch索引数据量过大的优化与部署策略

    目录 ​​​​​​​ 引言 1. 分片和副本策略 1.1分片策略 1.1.1 数据量 1.1.2 查询和写入负载 1.1.3 硬件资源 1.1.4 高可用性 1.2.副本策略 1.2.1 冗余和可用性 1.2.2 查询性能 1.2.3 存储需求 2. 硬件和资源配置优化 2.1 选择高性能硬件 2.1.1 存储 2.1.2 内存 2.1.3 处理器 2.1.4 网络 2.2. JVM调

    2024年01月19日
    浏览(43)
  • Redis内存兜底策略——内存淘汰及回收机制

    Redis内存淘汰及回收策略都是Redis 内存优化兜底 的策略,那它们是如何进行 兜底 的呢?先来说明一下什么是内存淘汰和内存回收策略: Redis内存淘汰:当Redis的内存使用 超过配置 的限制时,根据一定的策略删除一些键,以 释放内存空间 Redis内存回收:Redis通过 定期删除 和

    2024年02月06日
    浏览(28)
  • Redis的内存淘汰策略

    Redis的内存淘汰策略是指在Redis的用于缓存的内存不足时,怎么处理需要新写入且需要申请额外空间的数据。 noeviction :当内存不足以容纳新写入数据时,新写入操作会报错。 allkeys-lru :当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。(这个是最常用

    2024年02月10日
    浏览(27)
  • Redis 内存淘汰策略详解

    Redis 是一款高性能的非关系型数据库,它支持多种数据结构,如字符串、哈希、列表、集合、有序集合和 HyperLogLog。Redis 可以用于缓存、消息队列、应用程序中的数据结构存储等场景,它的优点是响应速度快、支持丰富的数据结构和扩展性好。 Redis 将所有数据都存储在内存中

    2024年02月10日
    浏览(41)
  • Redis内存策略

    Redis是基于内存存储,所以其性能很强。但单节点的Redis内存不宜过大,否则会影响持久化或主从同步性能。 可以手动修改配置文件来设置Redis的最大内存 如果内存使用达到了上限,就无法存储更多的数据了。 Redis为尽量避免内存达到上限,提供了两种策略: 过期策略 、 淘

    2024年02月10日
    浏览(19)
  • redis 7.x 内存过期淘汰策略

    1.查看redis默认内存大小 config  get  maxmemory config set  maxmemory    1024 注意:在64-bit系统下,maxmemory设置为0表示不限制redis的内存使用。 LRU: 最近最少使用页面置换算法 ,查看页面最后一次被使用到发生调度的时间长度,首先淘汰最长时间未被使用的页面。 LFU:最近最不经常

    2024年02月07日
    浏览(36)
  • Redis10大性能优化策略(下)

    1)尽量不使用 O(N) 以上复杂度过高的命令,对于数据的聚合操作,放在客户端做。 2)执行 O(N) 命令,保证 N 尽量的小(推荐 N = 300),每次获取尽量少的数据,让 Redis 可以及时处理返回。 一般有两种方案来规避这个问题: 1.集中过期 key 增加一个随机过期时间,把集中过期

    2024年02月13日
    浏览(34)
  • 机器学习策略——优化深度学习系统

    老式电视机,有很多旋钮可以用来调整图像的各种性质,对于这些旧式电视,可能有一个旋钮用来调图像垂直方向的高度,另外有一个旋钮用来调图像宽度,也许还有一个旋钮用来调梯形角度,还有一个旋钮用来调整图像左右偏移,还有一个旋钮用来调图像旋转角度之类的。

    2024年02月10日
    浏览(24)
  • Redis内存优化——内存淘汰及回收机制

    本文是系列文章,为了增强您的阅读体验,已将系列文章目录放入文章末尾。👍👍👍 Redis内存淘汰及回收策略都是Redis 内存优化兜底 的策略,那它们是如何进行 兜底 的呢?先来说明一下什么是内存淘汰和内存回收策略: Redis内存淘汰:当Redis的内存使用 超过配置 的限制时

    2024年02月08日
    浏览(28)
  • 机器学习策略二——优化深度学习系统

    如果你希望让学习算法能够胜任人类能做的任务,但你的学习算法还没有达到人类的表现,那么人工检查一下你的算法犯的错误也许可以让你了解接下来应该做什么。这个过程称为错误分析。 假设你正在调试猫分类器,然后你取得了90%准确率,相当于10%错误,在你的开发集上

    2024年02月09日
    浏览(19)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包