mirror of
https://github.com/fluencelabs/redis
synced 2025-03-19 17:10:50 +00:00
Add cached total system memory to INFO output
There is no standard cross-platform way of obtaining system memory info, but I found a useful function convering all common platforms. I removed support for uncommon Redis platforms (windows, AIX) and left others intact. For more info, see: http://nadeausoftware.com/articles/2012/09/c_c_tip_how_get_physical_memory_size_system The system memory info is cached on startup, but some systems may be able to change the amount of memory visible to Redis at runtime if Redis is deployed in a VM or container. Also see #1820
This commit is contained in:
parent
7d4c2a98b6
commit
ec5a0c548b
60
src/redis.c
60
src/redis.c
@ -53,6 +53,7 @@
|
|||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
|
||||||
/* Our shared "common" objects */
|
/* Our shared "common" objects */
|
||||||
|
|
||||||
@ -288,6 +289,7 @@ struct redisCommand redisCommandTable[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct evictionPoolEntry *evictionPoolAlloc(void);
|
struct evictionPoolEntry *evictionPoolAlloc(void);
|
||||||
|
static size_t getMemorySize(void);
|
||||||
|
|
||||||
/*============================ Utility functions ============================ */
|
/*============================ Utility functions ============================ */
|
||||||
|
|
||||||
@ -1759,6 +1761,7 @@ void initServer(void) {
|
|||||||
server.clients_waiting_acks = listCreate();
|
server.clients_waiting_acks = listCreate();
|
||||||
server.get_ack_from_slaves = 0;
|
server.get_ack_from_slaves = 0;
|
||||||
server.clients_paused = 0;
|
server.clients_paused = 0;
|
||||||
|
server.system_memory_size = getMemorySize();
|
||||||
|
|
||||||
createSharedObjects();
|
createSharedObjects();
|
||||||
adjustOpenFilesLimit();
|
adjustOpenFilesLimit();
|
||||||
@ -2479,7 +2482,6 @@ void timeCommand(redisClient *c) {
|
|||||||
addReplyBulkLongLong(c,tv.tv_usec);
|
addReplyBulkLongLong(c,tv.tv_usec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Helper function for addReplyCommand() to output flags. */
|
/* Helper function for addReplyCommand() to output flags. */
|
||||||
int addReplyCommandFlag(redisClient *c, struct redisCommand *cmd, int f, char *reply) {
|
int addReplyCommandFlag(redisClient *c, struct redisCommand *cmd, int f, char *reply) {
|
||||||
if (cmd->flags & f) {
|
if (cmd->flags & f) {
|
||||||
@ -2570,6 +2572,54 @@ void commandCommand(redisClient *c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the size of physical memory (RAM) in bytes.
|
||||||
|
* It looks ugly, but this is the cleanest way to achive cross platform results.
|
||||||
|
* Cleaned up from:
|
||||||
|
* http://nadeausoftware.com/articles/2012/09/c_c_tip_how_get_physical_memory_size_system
|
||||||
|
*/
|
||||||
|
size_t getMemorySize() {
|
||||||
|
#if defined(__unix__) || defined(__unix) || defined(unix) || \
|
||||||
|
(defined(__APPLE__) && defined(__MACH__))
|
||||||
|
#if defined(CTL_HW) && (defined(HW_MEMSIZE) || defined(HW_PHYSMEM64))
|
||||||
|
int mib[2];
|
||||||
|
mib[0] = CTL_HW;
|
||||||
|
#if defined(HW_MEMSIZE)
|
||||||
|
mib[1] = HW_MEMSIZE; /* OSX. --------------------- */
|
||||||
|
#elif defined(HW_PHYSMEM64)
|
||||||
|
mib[1] = HW_PHYSMEM64; /* NetBSD, OpenBSD. --------- */
|
||||||
|
#endif
|
||||||
|
int64_t size = 0; /* 64-bit */
|
||||||
|
size_t len = sizeof(size);
|
||||||
|
if (sysctl( mib, 2, &size, &len, NULL, 0) == 0)
|
||||||
|
return (size_t)size;
|
||||||
|
return 0L; /* Failed? */
|
||||||
|
|
||||||
|
#elif defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE)
|
||||||
|
/* FreeBSD, Linux, OpenBSD, and Solaris. -------------------- */
|
||||||
|
return (size_t)sysconf(_SC_PHYS_PAGES) * (size_t)sysconf(_SC_PAGESIZE);
|
||||||
|
|
||||||
|
#elif defined(CTL_HW) && (defined(HW_PHYSMEM) || defined(HW_REALMEM))
|
||||||
|
/* DragonFly BSD, FreeBSD, NetBSD, OpenBSD, and OSX. -------- */
|
||||||
|
int mib[2];
|
||||||
|
mib[0] = CTL_HW;
|
||||||
|
#if defined(HW_REALMEM)
|
||||||
|
mib[1] = HW_REALMEM; /* FreeBSD. ----------------- */
|
||||||
|
#elif defined(HW_PYSMEM)
|
||||||
|
mib[1] = HW_PHYSMEM; /* Others. ------------------ */
|
||||||
|
#endif
|
||||||
|
unsigned int size = 0; /* 32-bit */
|
||||||
|
size_t len = sizeof(size);
|
||||||
|
if (sysctl(mib, 2, &size, &len, NULL, 0) == 0)
|
||||||
|
return (size_t)size;
|
||||||
|
return 0L; /* Failed? */
|
||||||
|
#endif /* sysctl and sysconf variants */
|
||||||
|
|
||||||
|
#else
|
||||||
|
return 0L; /* Unknown OS. */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert an amount of bytes into a human readable string in the form
|
/* Convert an amount of bytes into a human readable string in the form
|
||||||
* of 100B, 2G, 100M, 4K, and so forth. */
|
* of 100B, 2G, 100M, 4K, and so forth. */
|
||||||
void bytesToHuman(char *s, unsigned long long n) {
|
void bytesToHuman(char *s, unsigned long long n) {
|
||||||
@ -2698,7 +2748,9 @@ sds genRedisInfoString(char *section) {
|
|||||||
if (allsections || defsections || !strcasecmp(section,"memory")) {
|
if (allsections || defsections || !strcasecmp(section,"memory")) {
|
||||||
char hmem[64];
|
char hmem[64];
|
||||||
char peak_hmem[64];
|
char peak_hmem[64];
|
||||||
|
char total_system_hmem[64];
|
||||||
size_t zmalloc_used = zmalloc_used_memory();
|
size_t zmalloc_used = zmalloc_used_memory();
|
||||||
|
size_t total_system_mem = server.system_memory_size;
|
||||||
char *evict_policy = maxmemoryToString();
|
char *evict_policy = maxmemoryToString();
|
||||||
|
|
||||||
/* Peak memory is updated from time to time by serverCron() so it
|
/* Peak memory is updated from time to time by serverCron() so it
|
||||||
@ -2710,6 +2762,8 @@ sds genRedisInfoString(char *section) {
|
|||||||
|
|
||||||
bytesToHuman(hmem,zmalloc_used);
|
bytesToHuman(hmem,zmalloc_used);
|
||||||
bytesToHuman(peak_hmem,server.stat_peak_memory);
|
bytesToHuman(peak_hmem,server.stat_peak_memory);
|
||||||
|
bytesToHuman(total_system_hmem,total_system_mem);
|
||||||
|
|
||||||
if (sections++) info = sdscat(info,"\r\n");
|
if (sections++) info = sdscat(info,"\r\n");
|
||||||
info = sdscatprintf(info,
|
info = sdscatprintf(info,
|
||||||
"# Memory\r\n"
|
"# Memory\r\n"
|
||||||
@ -2718,6 +2772,8 @@ sds genRedisInfoString(char *section) {
|
|||||||
"used_memory_rss:%zu\r\n"
|
"used_memory_rss:%zu\r\n"
|
||||||
"used_memory_peak:%zu\r\n"
|
"used_memory_peak:%zu\r\n"
|
||||||
"used_memory_peak_human:%s\r\n"
|
"used_memory_peak_human:%s\r\n"
|
||||||
|
"total_system_memory:%lu\r\n"
|
||||||
|
"total_system_memory_human:%s\r\n"
|
||||||
"used_memory_lua:%lld\r\n"
|
"used_memory_lua:%lld\r\n"
|
||||||
"mem_fragmentation_ratio:%.2f\r\n"
|
"mem_fragmentation_ratio:%.2f\r\n"
|
||||||
"mem_allocator:%s\r\n"
|
"mem_allocator:%s\r\n"
|
||||||
@ -2727,6 +2783,8 @@ sds genRedisInfoString(char *section) {
|
|||||||
server.resident_set_size,
|
server.resident_set_size,
|
||||||
server.stat_peak_memory,
|
server.stat_peak_memory,
|
||||||
peak_hmem,
|
peak_hmem,
|
||||||
|
(unsigned long)total_system_mem,
|
||||||
|
total_system_hmem,
|
||||||
((long long)lua_gc(server.lua,LUA_GCCOUNT,0))*1024LL,
|
((long long)lua_gc(server.lua,LUA_GCCOUNT,0))*1024LL,
|
||||||
zmalloc_get_fragmentation_ratio(server.resident_set_size),
|
zmalloc_get_fragmentation_ratio(server.resident_set_size),
|
||||||
ZMALLOC_LIB,
|
ZMALLOC_LIB,
|
||||||
|
@ -908,6 +908,8 @@ struct redisServer {
|
|||||||
int assert_line;
|
int assert_line;
|
||||||
int bug_report_start; /* True if bug report header was already logged. */
|
int bug_report_start; /* True if bug report header was already logged. */
|
||||||
int watchdog_period; /* Software watchdog period in ms. 0 = off */
|
int watchdog_period; /* Software watchdog period in ms. 0 = off */
|
||||||
|
/* System hardware info */
|
||||||
|
size_t system_memory_size; /* Total memory in system as reported by OS */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct pubsubPattern {
|
typedef struct pubsubPattern {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user