一、redis内存分配器
Redis 是一种内存数据库,将数据保存在内存中,读写效率要比传统的将数据保存在磁盘上的数据库要快很多。Redis并没有自己实现内存池,利用了系统内存分配器,所以系统内存分配器的性能及碎片率会对Redis造成一些性能上的影响。
Redis在编译时便会指定内存分配器;内存分配器可以是 libc 、jemalloc或者tcmalloc,默认是jemalloc。如果是RPM安装的话,一般都是jemalloc。
如果自行编译的话,jemalloc源码包在redis源码的deps/jemalloc目录,如果遇到"error: jemalloc/jemalloc.h: No such file or directory",需要进入deps/jemalloc目录make一下,不要按照网上的说法直接使用"make MALLOC=libc"。
下图就是生产环境使用libc内存分配器造成碎片率过高的情况,我们不得不重新编译更换了jemalloc内存分配器。
二、内存碎片
Redis 进程内消耗主要包括:自身内存 + 对象内存 + 缓冲内存 + 内存碎片,其中 Redis 空进程自身内存消耗非常少,通常 used_memory_rss 在 3MB 左右时,used_memory 一般在 800KB 左右,一个空的 Redis 进程消耗内存可以忽略不计。
内存碎片率的计算公式,如下
三、redis内存碎片清理
当redis碎片率过高,有什么办法可以清理碎片呢?
在redis4.0之前的版本,好像没什么好方法,只能重启下redis进程,在4.0以后,redis有了手动清理和自动清理的命令。
手动清理
memory purge
#仅限4.0以上并且使用了jemalloc分配器
自动清理
config set activedefrag yes
#仅限4.0以上并且使用了jemalloc分配器
在4.0和5.0中状态是EXPERIMENTAL,6.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
官方的默认设置是:内存碎片率大于10%且内存碎片大小超过100mb。
redis在内存碎片整理时,会占用系统资源,导致redis响应慢,因此对于碎片整理的时机(触发条件)和整理力度(资源占用)需要仔细斟酌,下面的生产环境配置仅供参考:
active-defrag-ignore-bytes 500mb
active-defrag-threshold-lower 50
active-defrag-threshold-upper 100
active-defrag-cycle-min 5
active-defrag-cycle-max 10
注意:
active-defrag-threshold-lower的计算方法和mem_fragmentation_ratio的计算不太一样,是从jemalloc统计中取值,如下,
jemalloc统计值可以使用memory malloc-stats命令看到
参考资料
https://my.oschina.net/watliu/blog/1620666
https://zhuanlan.zhihu.com/p/67381368
http://remcarpediem.net/article/516957d3/
转载请注明:IPCPU-网络之路 » redis内存分配器和内存碎片清理