在Redis 4.O-RC3版本之后,Redis自身提供了一种清除内存碎片的方法
清除的原理很简单,通过复制拷贝将不连续的存放的数据搬到一起形成一块连续的内存空间,如下图:
如上图,清除之前A和B不是连续的,中间隔着两个字节空闲1,但是在执行清除内存碎片操作之后,Redis拷贝了B到空闲1,释放掉之前B的空间,此时空闲1和空闲2则变成了连续的空闲空间了。
那么问题来了,这种方式固然好,但是对于单线程的Redis来说,通过这种拷贝复制的方式显然是一种耗时的操作,性能大大降低,那么有什么好的方法呢?
Redis提供了参数配置,可以控制清除内存碎片的时机,命令如下:
config set activedefrag yes
以上命令启动自动清理,但是具体什么时候清理,还要受以下两个参数的影响:
- active-defrag-ignore-bytes 400mb:如果内存碎片达到了408mb,开始清理(自定义)
- active-defrag-threshold-lower 20:内存碎片空间占操作系统分配给Redis的总空间比例达到20%时,开始清理(自定义)
以上两个参数只有全部满足才会开始清理
除了以上触发清理内存碎片的参数,Redis还提供了两个参数来保证在清理过程中不影响处理正常的请求,如下:
1. active-defrag-cycle-min 25:表示自动清理过程所用CPU时间的比例不低于25%,保证清理能正常开展
2. active-defrag-cycle-max 75:表示自动清理过程所用CPU时间的比例不高于75%,一旦超过,就停止清理,从而避免在清理时,大量的内存拷贝阻塞 Redis,导致响应延迟升高。
以上两个参数控制了清理过程中的CPU时间占比,保证了正常处理请求不受影响