Redis内存突增,如何精准量化内存使用状况?

摘要:背景 最近碰到一个 case,一个 Redis 实例的内存突增,used_memory最大时达到了 78.9G,而该实例的maxmemory配置却只有 16G,最终导致实例中的数据被大量驱逐。 以下是问题发生时INFO MEMORY的部分输
背景 最近碰到一个 case,一个 Redis 实例的内存突增,used_memory最大时达到了 78.9G,而该实例的maxmemory配置却只有 16G,最终导致实例中的数据被大量驱逐。 以下是问题发生时INFO MEMORY的部分输出内容。 #Memory used_memory:84716542624 used_memory_human:78.90G used_memory_rss:104497676288 used_memory_rss_human:97.32G used_memory_peak:84716542624 used_memory_peak_human:78.90G used_memory_peak_perc:100.00% used_memory_overhead:75682545624 used_memory_startup:906952 used_memory_dataset:9033997000 used_memory_dataset_perc:10.66% allocator_allocated:84715102264 allocator_active:101370822656 allocator_resident:102303637504 total_system_memory:810745470976 total_system_memory_human:755.07G used_memory_lua:142336 used_memory_lua_human:139.00K used_memory_scripts:6576 used_memory_scripts_human:6.42K number_of_cached_scripts:13 maxmemory:17179869184 maxmemory_human:16.00G maxmemory_policy:volatile-lru allocator_frag_ratio:1.20 allocator_frag_bytes:16655720392 内存突增导致数据被驱逐,是 Redis 中一个较为常见的问题。很多童鞋在面对这类问题时往往缺乏清晰的分析思路,常常误以为是复制、RDB 持久化等操作引起的。接下来,我们看看如何系统地分析这类问题。 本文主要包括以下几部分: INFO 中的used_memory是怎么来的? 什么是used_memory? used_memory内存通常会被用于哪些场景? Redis 7 在内存统计方面的变化。 数据驱逐的触发条件——当used_memory超过maxmemory后,是否一定会触发驱逐? 最后,分享一个脚本,帮助实时分析used_memory增长时,具体是哪一部分的内存消耗导致的。 INFO 中的 used_memory 是怎么来的? 当我们执行INFO命令时,Redis 会调用genRedisInfoString函数来生成其输出。 //server.c sdsgenRedisInfoString(constchar*section){ ... /*Memory*/ if(allsections||defsections||!strcasecmp(section,"memory")){ ... size_tzmalloc_used=zmalloc_used_memory(); ... if(sections++)info=sdscat(info,"\r\n"); info=sdscatprintf(info, "#Memory\r\n" "used_memory:%zu\r\n" "used_memory_human:%s\r\n" "used_memory_rss:%zu\r\n" ... "lazyfreed_objects:%zu\r\n", zmalloc_used, hmem, server.cron_malloc_stats.process_rss, ... lazyfreeGetFreedObjectsCount() ); freeMemoryOverheadData(mh); } ... returninfo; } 可以看到,used_memory 的值来自 zmalloc_used,而 zmalloc_used 又是通过zmalloc_used_memory()函数获取的。
阅读全文