前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis 内存碎片分析

Redis 内存碎片分析

原创
作者头像
夜半钟鸣
修改2021-02-09 16:38:12
2.8K0
修改2021-02-09 16:38:12
举报
文章被收录于专栏:小树洞

内存碎片产生原因

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

比如程序申请一个20字节的内存,内存分配器会分配一个32字节的内存空间,这么做是为了减少分配次数。

  • redis会申请不同大小的内存空间来存储不同业务不同类型的数据,由于内存按照固定大小分配且会比实际申请的内存要大一些,这个过程中会产生内存碎片
    image.png
    image.png
  • redis的键值对会被修改和删除,产生内存碎片
    image.png
    image.png

怎么判断存在内存碎片

redis的info memory命令可以帮助我们判断当前实例是否存在内存碎片

代码语言:txt
复制
INFO memory
# Memory
used_memory:1073741736         ## redis实际申请的内存空间大小
used_memory_human:1024.00M
used_memory_rss:1997159792     ## OS分配给redis的物理内存空间,其中包含内存碎片
used_memory_rss_human:1.86G
…
mem_fragmentation_ratio:1.86

指标mem_fragmentation_ratio:1.86 表示当前的内存碎片率,

计算公式为mem_fragmentation_ratio = used_memory_rss/ used_memory

所以,mem_fragmentation_ratio=1应该是最理想的情况

内存碎片严重程度

产生内存碎片不可避免,那么内存碎片率达到多少需要进行清理呢,这里有个经验阈值

  • 1 < mem_fragmentation_ratio < 1.5 ,可以认为是合理的,无需处理
  • mem_fragmentation_ratio > 1.5, 表示内存碎片率超过50%,需要进行处理

当然还有可能存在一种情况,即内存碎片率 小于1:

这时候就说明used_memory_rss < used_memory,即操作系统分配给redis的物理内存 小于 redis实际存储数据的内存。这种情况下,就会存在一部分redis的数据被换到了swap中,当redis访问这部分数据时就会有严重的性能问题,需要考虑进行扩容或者集群改造了。

如何清理内存碎片

自动清理

Redis 4.0-RC3 + 版本提供了内存碎片自动清理的办法,其基本思想是“搬家让位,合并空间”

启用自动清理功能
代码语言:txt
复制
config set activedefrag yes

这里我设置activedefrag参数时遇到下面的报错

代码语言:txt
复制
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

原因:Redis使用的内存分配器可以是libc、jemalloc、tcmalloc,源码编译安装时默认是jemalloc,自动清理内存碎片的功能需要该redis的内存分配器是jemalloc时才能启用。

我这边的内存分配器是libc

代码语言:txt
复制
$ redis-cli info memory|grep mem_allocator
mem_allocator:libc

解决:需要重新编译安装。生产环境的话,如果必须要开自动清理功能,主从或集群架构可以通过切主来避免业务影响,单机的话则需要做好数据备份后安排停机窗口然后重编译。

触发时机

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

代码语言:txt
复制
active-defrag-ignore-bytes 100mb    # 默认100MB,表示内存碎片空间达到100MB时
active-defrag-threshold-lower 10    # 默认10,表示内存碎片空间占OS分配给redis的物理内存空间的比例达到10%时 
控制参数

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

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

手动清理

除了开启内存碎片自动清理策略,redis从4.0.0版本后也支持手动清理内存碎片,通过如下命令实现

代码语言:txt
复制
127.0.0.1:6379> memory purge
OK

需要注意的是,该清理命令也只当redis的内存分配器是==jemalloc==时才能生效

参考资料

https://redis-doc-test.readthedocs.io/

https://time.geekbang.org/column/article/289140

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 内存碎片产生原因
  • 怎么判断存在内存碎片
  • 内存碎片严重程度
  • 如何清理内存碎片
    • 自动清理
      • 启用自动清理功能
      • 触发时机
      • 控制参数
    • 手动清理
    • 参考资料
    相关产品与服务
    云数据库 Redis®
    腾讯云数据库 Redis®(TencentDB for Redis®)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档