1、Redis 存储数据的时候向操作系统申请的内存空间可能会大于数据实际需要的存储空间。以下是这段 Redis 官方的原话:To store user keys, Redis allocates at most as much memory as the maxmemory setting enables (however there are small extra allocations possible).Redis 使用 zmalloc 方法(Redis 自己实现的内存分配方法)进行内存分配的时候,除了要分配 size 大小的内存之外,还会多分配 PREFIX_SIZE 大小的内存。
Redis 内存碎片率的计算公式:mem_fragmentation_ratio (内存碎片率)= used_memory_rss (操作系统实际分配给 Redis 的物理内存空间大小)/ used_memory(Redis 内存分配器为了存储数据实际申请使用的内存空间大小)也就是说,mem_fragmentation_ratio (内存碎片率)的值越大代表内存碎片率越严重。一定不要误认为used_memory_rss 减去 used_memory值就是内存碎片的大小!!!这不仅包括内存碎片,还包括其他进程开销,以及共享库、堆栈等的开销。很多小伙伴可能要问了:“多大的内存碎片率才是需要清理呢?”。通常情况下,我们认为 mem_fragmentation_ratio > 1.5 的话才需要清理内存碎片。 mem_fragmentation_ratio > 1.5 意味着你使用 Redis 存储实际大小 2G 的数据需要使用大于 3G 的内存。
Redis4.0-RC3 版本以后自带了内存整理,可以避免内存碎片率过大的问题。直接通过 config set 命令将 activedefrag 配置项设置为 yes 即可。config set activedefrag yes
具体什么时候清理需要通过下面两个参数控制:# 内存碎片占用空间达到 500mb 的时候开始清理
config set active-defrag-ignore-bytes 500mb
内存碎片率大于 1.5 的时候开始清理
config set active-defrag-threshold-lower 50
通过 Redis 自动内存碎片清理机制可能会对 Redis 的性能产生影响,我们可以通过下面两个参数来减少对 Redis 性能的影响:# 内存碎片清理所占用 CPU 时间的比例不低于 20%
config set active-defrag-cycle-min 20
内存碎片清理所占用 CPU 时间的比例不高于 50%
config set active-defrag-cycle-max 50
另外,重启节点可以做到内存碎片重新整理。如果你采用的是高可用架构的 Redis 集群的话,你可以将碎片率过高的主节点转换为从节点,以便进行安全重启。