redis内存碎片过高
mem_fragmentation_ratio >1.5
个人博客有详细代码
一、内存使用统计
二、内存碎片率高的原因
三、解决方法
一、内存使用统计
需要重点关注的指标有:used_memory_rss和used_memory以及它们的比 mem_fragmentation_ratio
used_memory :Redis使用其分配器分配的内存大小,已经使用了的内存大小
used_memory_human:用户数据所占用的内存,就是你缓存的数据的大小
used_memory_rss :操作系统分配给Redis实例的内存大小,表示该进程所占物理内存的大小
mem_fragmentation_ratio = used_memory_rss / used_memory
两者包括了实际缓存占用的内存和Redis自身运行所占用的内存,used_memory_rss指标还包含了内存碎片的开销,内存碎片是由操作系统低效的分配/回收物理内存导致的。
mem_fragmentation_ratio < 1 表示Redis内存分配超出了物理内存,操作系统正在进行内存交换,内存交换会引起非常明显的响应延迟;
mem_fragmentation_ratio > 1 是合理的;
mem_fragmentation_ratio > 1.5 说明Redis消耗了实际需要物理内存的150%以上,其中50%是内存碎片率,可能是操作系统或Redis实例中内存管理变差的表现
二、内存碎片率高的原因
分析实际环境,因为该redis主要是存储频繁更新的数据,每次更新数据之前,redis会删除旧的数据,实际上,由于Redis释放了内存块,但内存分配器并没有返回内存给操作系统,这个内存分配器是在编译时指定的,可以是libc、jemalloc或者tcmalloc。used_memory_rss会越来越大,导致mem_fragmentation_ratio越来越高
遇到变长key-value负载:存储的数据长短差异较大,频繁更新,redis的每个k-v对初始化的内存大小是最适合的,当修改的value改变的并且原来内存大小不适用的时候,就需要重新分配内存。重新分配之后,就会有一部分内存redis无法正常回收,一直占用着。
maxmemory限制导致key被回收删除
redis写入大量数据,这些数据的key和原来的数据很多不一致,数据超过maxmemory限制后redis会通过key的回收策略将部分旧数据淘汰,而被淘汰的数据本身占用的内存却没有被redis进程释放,导致redis内存的有效数据虽然没有超过最大内存,但是整个进程的内存在一直增长
三、解决方法
1、重启Redis服务器可以让额外产生的内存碎片失效并重新作为新内存来使用,使操作系统恢复高效的内存管理修改内存分配器。
redis支持glibc’s malloc、jemalloc11、tcmalloc几种不同的内存分配器,每个分配器在内存分配和碎片上都有不同的实现。不建议普通管理员修改Redis默认内存分配器,因为这需要完全理解这几种内存分配器的差异,也要重新编译Redis
2、redis4.0以上可以使用新增指令来手动回收内存碎片,配置监控使用性能更佳。
警告此功能是实验性的。然而,即使在生产中也进行了压力测试,并且由多个工程师手动测试了一段时间
什么是主动碎片整理?
自动(实时)碎片整理允许Redis服务器压缩内存中小数据分配和数据释放之间的空间,从而允许回收内存。
配置文件如下:
activedefrag yes 开启自动内存碎片整理(总开关)
代码全体内容在个人博客点击跳转