什么是内存碎片
内存碎片率:mem_fragmentation_ratio
mem_fragmentation_ratio指数>1表明有内存碎片,越大表明越多,<1表明正在使用虚拟内存,虚拟内存其实就是硬盘,性能比内存低得多,这是应该增强机器的内存以提高性能。
一般来说,mem_fragmentation_ratio的数值在1 ~ 1.5之间是比较健康的。
大于1.5表示,系统分配的内存大于Redis实际使用的内存,Redis没有把这部分内存返还给系统,产生了很多内存碎片。在Redis 4.0版以前,只能通过安全重启解决这个问题。
小于1表示,系统分配的内存小于Redis实际使用的内存,而Redis很有可能在使用Swap了!使用swap是相当影响性能的。
查看内存碎片方法:redis> info memory
mem_fragmentation_ratio的计算公式为:UsedMemory/RssUsedMemory
内存碎片是怎么产生的
redis内存分配规则
在编译时指定的Redis使用的内存分配器,可以是libc、jemalloc、tcmalloc,默认是jemalloc。
jemalloc在64位系统中,将内存空间划分为小、大、巨大三个范围;每个范围内又划分了许多小的内存块单位;存储数据的时候,会选择大小最合适的内存块进行存储。
jemalloc划分的内存单元如下图所示:
也就是说redis是以指定大小的块为单位进行连续内存分配的,而不是按需分配的。Redis 会根据申请的内存最接近的固定值分配相应大小的空间。
这就像你有不同的箱子,为了装东西,你需要找一个体积最接近的箱子来装。但是装进去后,你发现还有空间可以放一些小东西,就无需再找箱子了。但是,这种分配空间的方式会带来一定程度的内存碎片。我们可以把固定大小的划分空间看成不同体积的箱子,每种箱子里的空间不同程度上都会有剩余。这些剩余的空间就是内存碎片。
产生原因
写入数据时,Redis 为了减少分配次数在分配内存是根据固定的大小来划分内存空间的。修改数据时会释放或占用额外的内存空间,删除数据时会释放空间。这样就会产生不同程度的内存碎片。
如何控制内存碎片
正常重启redis实例(正常关闭实例会生成rdb备份文件的,关闭aof方式,以加快重启时数据加载速度)
内存碎片整理(redis4.0+)
redis> config set activedefrag yes
#碎片整理总开关
activedefrag yes
#当碎片达到 100mb 时,开启内存碎片整理
active-defrag-ignore-bytes 100mb
#当碎片超过 10% 时,开启内存碎片整理
active-defrag-threshold-lower 10
#内存碎片超过 100%,则尽最大努力整理
active-defrag-threshold-upper 100
#内存自动整理占用资源最小百分比
active-defrag-cycle-min 5
#内存自动整理占用资源最大百分比
active-defrag-cycle-max 50