redis调优 -- 内存碎片

最近查看了一下redis运行情况,发现公司测试服务器的redis内存不太够用,可是实际占用内存的数据量其实不大,之前也没有这种状况,以前在cache层新增了一个防刷积分任务的逻辑才会这样,搜索一下缘由,发现原来是产生了大量的内存碎片。redis

首先,查看redis的内存状态,要用info memory指令缓存

2018-06-01_110028.png

ps:(这个是我flushdb后的结果,反面教材来的。。。) 图中几个参数的意义:服务器

一、used_memory:ide

已经使用了的内存大小,包括redis进程内部开销和你的cache的数据所占用的内存,单位byte。性能

二、used_memory_human:测试

用户数据所占用的内存,就是你缓存的数据的大小。lua

三、used_memory_rss:(rss for Resident Set Size)blog

表示redis物理内存的大小,即向OS申请了多少内存使用与used_memory的区别在后面解释。进程

四、used_memory_peak:图片

redis内存使用的峰值。

五、used_memory_peak_human:

用户cache数据的峰值大小。

六、used_memory_lua:

执行lua脚本所占用的内存。

七、mem_fragmentation_ratio:

内存碎片率,计算公式:190138549569988.png ratio指数>1代表有内存碎片,越大代表越多,<1代表正在使用虚拟内存,虚拟内存其实就是硬盘,性能比内存低得多,这是应该加强机器的内存以提升性能。通常来讲,mem_fragmentation_ratio的数值在1 ~ 1.5之间是比较健康的。

八、mem_allocator:

在编译时指定的Redis使用的内存分配器,能够是libc、jemalloc、tcmalloc,默认是jemalloc。jemalloc在64位系统中,将内存空间划分为小、大、巨大三个范围;每一个范围内又划分了许多小的内存块单位;存储数据的时候,会选择大小最合适的内存块进行存储。 jemalloc划分的内存单元以下图所示: 1174710-20180327001126509-2023165562.png (图侵删)


产生缘由

能够这样认为,redis产生内存碎片有两个缘由, A:redis自身的内存分配器。 B:修改cache的值,且修改后的value与原来value的大小差别较大。

进程须要用内存的话,会先经过OS向device申请,而后才可以使用。通常进程在不须要使用的时候,会释放掉这部份内存并返回给device。可是redis做者可能为了更高的性能,因此在redis中实现了本身的内存分配器来管理内存,不会立刻返还内存,不用每次都向OS申请了,从而实现高性能。

可是,在内存分配器的那张图片咱们知道,redis的每一个k-v对初始化的内存大小是最适合的,当这个value改变的而且原来内存大小不适用的时候,就须要从新分配内存了。(可是value存比原来小不知道会不会产生碎片)。从新分配以后,就会有一部份内存redis没法正常回收,一直占用着。


知道了缘由就能够解决问题了,网上找到了两个解决方案: 一、重启redis服务,简单粗暴。 二、redis4.0以上可使用新增指令来手动回收内存碎片,配置监控使用性能更佳,具体你们能够本身去查。

相关文章
相关标签/搜索