From 250e7f690825f506306e3c091ba4465c206726bd Mon Sep 17 00:00:00 2001 From: antirez Date: Thu, 8 Mar 2012 16:15:37 +0100 Subject: [PATCH] Instantaneous ops/sec figure in INFO output. --- src/redis.c | 33 +++++++++++++++++++++++++++++++++ src/redis.h | 7 +++++++ 2 files changed, 40 insertions(+) diff --git a/src/redis.c b/src/redis.c index acc01b4b..03dc2ed1 100644 --- a/src/redis.c +++ b/src/redis.c @@ -616,6 +616,31 @@ void updateLRUClock(void) { REDIS_LRU_CLOCK_MAX; } + +/* Add a sample to the operations per second array of samples. */ +void trackOperationsPerSecond(void) { + long long t = mstime() - server.ops_sec_last_sample_time; + long long ops = server.stat_numcommands - server.ops_sec_last_sample_ops; + long long ops_sec; + + ops_sec = t > 0 ? (ops*1000/t) : 0; + + server.ops_sec_samples[server.ops_sec_idx] = ops_sec; + server.ops_sec_idx = (server.ops_sec_idx+1) % REDIS_OPS_SEC_SAMPLES; + server.ops_sec_last_sample_time = mstime(); + server.ops_sec_last_sample_ops = server.stat_numcommands; +} + +/* Return the mean of all the samples. */ +long long getOperationsPerSecond(void) { + int j; + long long sum = 0; + + for (j = 0; j < REDIS_OPS_SEC_SAMPLES; j++) + sum += server.ops_sec_samples[j]; + return sum / REDIS_OPS_SEC_SAMPLES; +} + int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { int j, loops = server.cronloops; REDIS_NOTUSED(eventLoop); @@ -628,6 +653,8 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { * To access a global var is faster than calling time(NULL) */ server.unixtime = time(NULL); + trackOperationsPerSecond(); + /* We have just 22 bits per object for LRU information. * So we use an (eventually wrapping) LRU clock with 10 seconds resolution. * 2^22 bits with 10 seconds resoluton is more or less 1.5 years. @@ -1091,6 +1118,10 @@ void initServer() { server.stat_peak_memory = 0; server.stat_fork_time = 0; server.stat_rejected_conn = 0; + memset(server.ops_sec_samples,0,sizeof(server.ops_sec_samples)); + server.ops_sec_idx = 0; + server.ops_sec_last_sample_time = mstime(); + server.ops_sec_last_sample_ops = 0; server.unixtime = time(NULL); server.lastbgsave_status = REDIS_OK; server.stop_writes_on_bgsave_err = 1; @@ -1726,6 +1757,7 @@ sds genRedisInfoString(char *section) { "# Stats\r\n" "total_connections_received:%lld\r\n" "total_commands_processed:%lld\r\n" + "instantaneous_ops_per_sec:%lld\r\n" "rejected_connections:%lld\r\n" "expired_keys:%lld\r\n" "evicted_keys:%lld\r\n" @@ -1736,6 +1768,7 @@ sds genRedisInfoString(char *section) { "latest_fork_usec:%lld\r\n", server.stat_numconnections, server.stat_numcommands, + getOperationsPerSecond(), server.stat_rejected_conn, server.stat_expiredkeys, server.stat_evictedkeys, diff --git a/src/redis.h b/src/redis.h index ee1cef4c..8d492596 100644 --- a/src/redis.h +++ b/src/redis.h @@ -59,6 +59,7 @@ #define REDIS_REPL_PING_SLAVE_PERIOD 10 #define REDIS_RUN_ID_SIZE 40 +#define REDIS_OPS_SEC_SAMPLES 16 /* Protocol and I/O related defines */ #define REDIS_MAX_QUERYBUF_LEN (1024*1024*1024) /* 1GB max query buffer. */ @@ -606,6 +607,12 @@ 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 */ + /* 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) */ + long long ops_sec_last_sample_ops; /* numcommands in last sample */ + long long ops_sec_samples[REDIS_OPS_SEC_SAMPLES]; + int ops_sec_idx; /* Configuration */ int verbosity; /* Loglevel in redis.conf */ int maxidletime; /* Client timeout in seconds */ -- GitLab