文章目录

  • 【关于作者】
  • 1.内存碎片
  • 2.内存碎片如何形成
  • 2.1.内因:内存分配器的分配策略
  • 2.2.外因:键值对大小不一致和删改操作
  • 3.如何判断是否有内存碎片
  • 4.如何清理内存碎片
  • 4.1.直接重启redis实例(不推荐)
  • 4.2.redis4.0-RC3,自身提供方法


【关于作者】

关于作者,目前在蚂蚁金服搬砖任职,在支付宝营销投放领域工作了多年,目前在专注于内存数据库相关的应用学习,如果你有任何技术交流或大厂内推及面试咨询

redis 分片内存满了 redis 内存碎片_学习

1.内存碎片

概念:

应用申请内存总是一块连续的空间,可能机器的内存剩余容量够但是应用无法正常的申请内存,由于剩余内存没有连续的大小为N的内存了,正是由于这些剩余内存都是内存碎片导致的,可以理解为连续空间中间断的未使用内存。如下图的空闲字节1、2:

redis 分片内存满了 redis 内存碎片_redis 分片内存满了_02

2.内存碎片如何形成

2.1.内因:内存分配器的分配策略

**内存分配器:**一般都是按照大小进行内存分配,而不是按照应用程序申请的空间,redis分配器包括libc、jemalloc、tcmalloc,默认使用jemalloc

jemalloc分配器:jemalloc的分配策略(外因)之一就是按照固定大小8字节、16字节、32字节、48字节,…, 2KB、4KB、8KB分配空间,申请大小N,则分配2的次幂大于且最接近N的空间大小进行分配、好处在于多分配的空间等再次需要且这块多余的空间能满足时,无需重复分配,减少分配次数,但是这样会导致分配多余的空间成为内存碎片

redis 分片内存满了 redis 内存碎片_数据库_03

2.2.外因:键值对大小不一致和删改操作

  • 根据应用需求,不同大小的键值对,会有不同大小的空间需求
  • redis的键值对会被删除修改,会导致空间的扩容和释放
    如下图:

大量内存碎片的存在,会导致redis的利用率变低

3.如何判断是否有内存碎片

Redis的INFO命令

INFO memory
# Memory
used_memory:1073741736
used_memory_human:1024.00M
used_memory_rss:1997159792
used_memory_rss_human:1.86G
…
mem_fragmentation_ratio:1.86

这里有一个mem_fragmentation_ratio的指标,它表示的就是Redis当前的内存碎片率。那么,这个碎片率是怎么计算的呢?其实,就是上面的命令中的两个指标used_memory_rssused_memory相除的结果:mem_fragmentation_ratio = used_memory_rss/ used_memory

used_memory_rss:操作系统实际分配给redis的内存

used_memory:redis为了保存数据实际申请使用的空间

  • mem_fragmentation_ratio 大于1但小于1.5:正常情况、内外因下无法避免
  • mem_fragmentation_ratio 大于 1.5:内存碎片率已经大于了50%,这时需要考虑降低内存碎片率了
  • **mem_fragmentation_ratio小于1:**redis没有足够的内存可以使用了,会导致redis一部分的内存数据会被换到swap中,之后redis访问swap中的数据延迟会变大,性能下降

4.如何清理内存碎片

4.1.直接重启redis实例(不推荐)

4.2.redis4.0-RC3,自身提供方法

基本机制:搬家让位,合并空间

一块连续的空间被分割成好几块不连续的空间时,操作系统就会将数据拷贝到别处。数据拷贝就将这些数据原本的位置空出来,使空间变为一段连续的空间

redis 分片内存满了 redis 内存碎片_redis_04

碎片清理是有代价的,拷贝清理的过程会阻塞redis的主进程,并且拷贝有时需要顺序,会进一步增大redis的等待时间

不过我们可以通过设置redis的参数来控制redis碎片清理的开始时间、结束时间、CPU的占用,从而减少对redis的影响

启用碎片清理:config set activedefrag yes

  • active-defrag-ignore-bytes 100mb:表示内存碎片的字节数达到100MB时,开始清理;
  • active-defrag-threshold-lower 10:表示内存碎片空间占操作系统分配给Redis的总空间比例达到10%时,开始清理

以上两个条件同时满足,才会开启内存清理。

还可以通过参数控制碎片清理CPU占用时间的上下限:

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