redis memory命令

ddatsh

db #redis redis

用户空间(user space)进程无法直接执行内核代码或者访问内核函数来分配内存资源,需要通过 系统调用接口 brk/sbrk(),请求系统内核来操作

系统调使 CPU 从用户态(user mode)切换到内核态(kernel mode),在需要频繁申请、释放内存的使用场景下会带来较大性能开销

为尽量减少brk/sbrk() 的调用次数,内存管理函数 malloc/free() 在实现上做了一定的优化

一般 free() 释放内存时不降低 programe break 位置,而是将需要释放的内存添加到 空闲内存列表 ,供 malloc() 函数后续循环使用

malloc() 申请内存时优先在空闲内存列表查找 >= 申请大小的内存块,直接返回 or 分割 or brk/sbrk

Redis 内存的管理机制依赖于 jemalloc/tcmalloc 等内存分配器(allocator)。删除 、清除过期 keys 等操作时调用 free() 函数释放内存可能并没有及时返还给操作系统,而是由内存分配器继续持有

Redis 可能会持有大量分配了却没有使用的内存空间,这部分空间被称为 内存碎片

内存碎片无法完全避免,只能降低碎片率

Redis 的内存碎片情况可以通过 INFO MEMORY 命令查看

redis memory 命令

4.0 前info memory只能查看 redis 内存大体使用状况,无法了解内存具体使用细节,比如expire的消耗client output buffer, query buffer

Memory 是Redis4.0 新特性,可用于分析详细内存使用情况,内存使用诊断,内存碎片回收等工作

memory help
help memory

info memory

# Redis 保存数据申请的内存空间
used_memory:
used_memory_human:

# 操作系统分配给 Redis 进程的内存空间 (used_memory_rss<used_memory可能是发生SWAP了)
used_memory_rss:
used_memory_rss_human:

# Redis 进程在运行过程中占用的内存峰值
used_memory_peak:
used_memory_peak_human:

# 内存碎片率,used_memory_rss / used_memory   (一般> 1.5 说明碎片过多需要清理了)
mem_fragmentation_ratio:

# Redis 最大可用内存,0表示不限制 (数据超出内存限制时执行 LRU 等删除策略)
maxmemory:0
maxmemory_human:0B

# 内存分配器
mem_allocator:jemalloc-5.x.x

内存碎片

9 字节内存空间, 1、2、3、5、6、9 已使用,如果计划申请 3 字节连续内存空间,按照现有内存使用情况无法申请, 4、7、8 就是“内存碎片”了

Redis 内存碎片主要如何形成

如何释放内存

重启redis

生产忽略之?

备用实例同步后替换

思路通,但操作流程复杂且风险高

memory purge 手动碎片整理

阻塞主进程,生产环境慎用

memory purge 和 activedefrag 回收的并不是同一块区域的内存,它简单粗暴的尝试清除脏页以便内存分配器回收。可以根据实际情况和 activedefrag 配合使用,memory purge 在极端情况下效果较好,activedefrag 则更彻底

activedefrag 自动碎片整理

activedefrag 默认关闭,计划清理碎片时需手动开启

config set activedefrag yes

配置项归类为三类,功能开关、碎片的整理力度、资源使用情况

功能开关

整理力度

资源占用

清理时机

mem_fragmentation_ratio > 1.5 时,建议开始清理内存碎片

也可以通过分析调整 activedefrag 参数配置从而达到自动清理效果

正常情况下尽量保持禁用状态

redis activedefrag

核心是利用 jemalloc 特性,不从线程缓存中获取内存,重新申请一块内存,从而将旧的有内存碎片的内存释放掉