(1)什么是内存碎片?

假如连续内存空间不足以分配给客户端申请的内存,就会导致内存分配失败,OOM或者其它错误。更简单的说,就是零散的内存碎片太多,没有真正可用的连续内存
例如:100M内存,客户端每次申请30M,连续申请三次后还剩下10M,这10M就称为不可用的内存碎片,当然这只是例子,实际不可能有10M这么大的碎片,一般都是很多以KB , B计算的碎片,加总和起来是非常大量的碎片。

(2)为什么会产生内存碎片?

Redis的增删改都会产生内存碎片
增:我们要针对key A set一个17字节的value,Redis并不会精准分配17字节的内存大小,而是分配32字节,这是因为Redis中的内存分配是固定大小划分内存空间的,例如:8,16,32,64,128……等等,类似一个个不同大小的箱子,我们的17虽然只超过16一点点,但是也是装不下,只能拿32的大号箱子装,下次再根据key A set value,只要value的大小不超过15字节,也可以放到这个箱子中,这样可以减少内存分配,但是也不可避免的出现了内存碎片。
删:参考上面的例子,假如有一个32字节的大箱子放着6条数据,删掉一条,那么这个大箱子就会空出来一部分内存空间,这一部分内存空间也是内存碎片。
改:还是一样的道理,本来一个32的箱子装着32的value,忽然value修改后只有30,那么空出来的2字节同样也是内存碎片

redis的内存大小分配在Redis的配置文件/usr/local/etc/redis.conf文件中,配置maxmemory,或者通过客户端命令:config set maxmemory 3GB 这样做限制

redis 碎片清理手动 redis内存碎片_内存碎片


如果没有手动配置,32位服务器默认是3GB,其它的没有做最大内存限制,也就是会无限制使用服务器内存,直到内存不足OOM,非常危险

(3)如何看内存碎片率情况?

通过客户端连接:redis-cli

查看Redis内存使用情况:info memory

redis 碎片清理手动 redis内存碎片_Redis_02


其中内存碎片率 = 占用物理内存 / 已使用内存,如果大于1,证明已使用内存小但是占用物理内存大,表明有内存碎片,如果<1,证明占用物理内存比使用内存小,所以使用的是虚拟内存(磁盘持久化存储),官网说这个参数在1~1.5是健康的内存使用状态。

另外:

所有XX_human的都是以人类可读的方式显示

所有的XX_memory_peak 指的是某项内存消耗峰值

total_system_memory是默认内存大小

(4)如何处理内存碎片?

要整理内存碎片的方式有两种:
1:重启redis(必须做好缓存备份或者开启持久化机制,详情参考另外一篇博客)
2:空间置换,类似JVM的标记整理清除算法,也就是使用命令回收内存碎片,但是会有性能损耗!会影响服务的响应!(4.0+的新版本才有这个功能)
具体配置如下:

开启自动内存碎片整理(总开关)

activedefrag yes

当碎片达到 100mb 时,开启内存碎片整理

active-defrag-ignore-bytes 100mb

当碎片超过 10% 时,开启内存碎片整理

active-defrag-threshold-lower 10

内存碎片超过 100%,则尽最大努力整理

active-defrag-threshold-upper 100

内存自动整理占用资源最小百分比

active-defrag-cycle-min 25

内存自动整理占用资源最大百分比

active-defrag-cycle-max 75