From 4ebc7e3738f7c5282a0a8dab0a589c84b307e90e Mon Sep 17 00:00:00 2001 From: antirez Date: Mon, 24 Mar 2014 12:00:20 +0100 Subject: [PATCH] Sample and cache RSS in serverCron(). Obtaining the RSS (Resident Set Size) info is slow in Linux and OSX. This slowed down the generation of the INFO 'memory' section. Since the RSS does not require to be a real-time measurement, we now sample it with server.hz frequency (10 times per second by default) and use this value both to show the INFO rss field and to compute the fragmentation ratio. Practically this does not make any difference for memory profiling of Redis but speeds up the INFO call significantly. --- src/redis.c | 8 ++++++-- src/redis.h | 1 + src/zmalloc.c | 4 ++-- src/zmalloc.h | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/redis.c b/src/redis.c index 9caeafa4..64c80bd9 100644 --- a/src/redis.c +++ b/src/redis.c @@ -1016,6 +1016,9 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { if (zmalloc_used_memory() > server.stat_peak_memory) server.stat_peak_memory = zmalloc_used_memory(); + /* Sample the RSS here since this is a relatively slow call. */ + server.resident_set_size = zmalloc_get_rss(); + /* We received a SIGTERM, shutting down here in a safe way, as it is * not ok doing so inside the signal handler. */ if (server.shutdown_asap) { @@ -1613,6 +1616,7 @@ void initServer() { /* A few stats we don't want to reset: server startup time, and peak mem. */ server.stat_starttime = time(NULL); server.stat_peak_memory = 0; + server.resident_set_size = 0; server.lastbgsave_status = REDIS_OK; server.aof_last_write_status = REDIS_OK; server.aof_last_write_errno = 0; @@ -2335,11 +2339,11 @@ sds genRedisInfoString(char *section) { "mem_allocator:%s\r\n", zmalloc_used, hmem, - zmalloc_get_rss(), + server.resident_set_size, server.stat_peak_memory, peak_hmem, ((long long)lua_gc(server.lua,LUA_GCCOUNT,0))*1024LL, - zmalloc_get_fragmentation_ratio(), + zmalloc_get_fragmentation_ratio(server.resident_set_size), ZMALLOC_LIB ); } diff --git a/src/redis.h b/src/redis.h index 4970dbdc..196c9246 100644 --- a/src/redis.h +++ b/src/redis.h @@ -625,6 +625,7 @@ struct redisServer { long long slowlog_entry_id; /* SLOWLOG current entry ID */ long long slowlog_log_slower_than; /* SLOWLOG time limit (to get logged) */ unsigned long slowlog_max_len; /* SLOWLOG max number of items logged */ + size_t resident_set_size; /* RSS sampled in serverCron(). */ /* The following two are used to track instantaneous "load" in terms * of operations per second. */ long long ops_sec_last_sample_time; /* Timestamp of last sample (in ms) */ diff --git a/src/zmalloc.c b/src/zmalloc.c index e7e97aa6..d0cf726c 100644 --- a/src/zmalloc.c +++ b/src/zmalloc.c @@ -321,8 +321,8 @@ size_t zmalloc_get_rss(void) { #endif /* Fragmentation = RSS / allocated-bytes */ -float zmalloc_get_fragmentation_ratio(void) { - return (float)zmalloc_get_rss()/zmalloc_used_memory(); +float zmalloc_get_fragmentation_ratio(size_t rss) { + return (float)rss/zmalloc_used_memory(); } #if defined(HAVE_PROC_SMAPS) diff --git a/src/zmalloc.h b/src/zmalloc.h index 331d8e43..72a4f813 100644 --- a/src/zmalloc.h +++ b/src/zmalloc.h @@ -73,7 +73,7 @@ char *zstrdup(const char *s); size_t zmalloc_used_memory(void); void zmalloc_enable_thread_safeness(void); void zmalloc_set_oom_handler(void (*oom_handler)(size_t)); -float zmalloc_get_fragmentation_ratio(void); +float zmalloc_get_fragmentation_ratio(size_t rss); size_t zmalloc_get_rss(void); size_t zmalloc_get_private_dirty(void); void zlibc_free(void *ptr); -- GitLab