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()函数获取的。
