diff --git a/src/expire.c b/src/expire.c index 81c9e23f..ce7882e4 100644 --- a/src/expire.c +++ b/src/expire.c @@ -111,7 +111,7 @@ void activeExpireCycle(int type) { if (clientsArePaused()) return; if (type == ACTIVE_EXPIRE_CYCLE_FAST) { - /* Don't start a fast cycle if the previous cycle did not exited + /* Don't start a fast cycle if the previous cycle did not exit * for time limt. Also don't repeat a fast cycle for the same period * as the fast cycle total duration itself. */ if (!timelimit_exit) return; @@ -140,6 +140,12 @@ void activeExpireCycle(int type) { if (type == ACTIVE_EXPIRE_CYCLE_FAST) timelimit = ACTIVE_EXPIRE_CYCLE_FAST_DURATION; /* in microseconds. */ + /* Accumulate some global stats as we expire keys, to have some idea + * about the number of keys that are already logically expired, but still + * existing inside the database. */ + long total_sampled = 0; + long total_expired = 0; + for (j = 0; j < dbs_per_call && timelimit_exit == 0; j++) { int expired; redisDb *db = server.db+(current_db % server.dbnum); @@ -192,7 +198,9 @@ void activeExpireCycle(int type) { ttl_sum += ttl; ttl_samples++; } + total_sampled++; } + total_expired += expired; /* Update the average TTL stats for this database. */ if (ttl_samples) { @@ -212,6 +220,7 @@ void activeExpireCycle(int type) { elapsed = ustime()-start; if (elapsed > timelimit) { timelimit_exit = 1; + server.stat_expired_time_cap_reached_count++; break; } } @@ -222,6 +231,16 @@ void activeExpireCycle(int type) { elapsed = ustime()-start; latencyAddSampleIfNeeded("expire-cycle",elapsed/1000); + + /* Update our estimate of keys existing but yet to be expired. + * Running average with this sample accounting for 5%. */ + double current_perc; + if (total_sampled) { + current_perc = (double)total_expired/total_sampled; + } else + current_perc = 0; + server.stat_expired_stale_perc = (current_perc*0.05)+ + (server.stat_expired_stale_perc*0.95); } /*----------------------------------------------------------------------------- diff --git a/src/server.c b/src/server.c index c14255db..1a6f3038 100644 --- a/src/server.c +++ b/src/server.c @@ -1799,6 +1799,8 @@ void resetServerStats(void) { server.stat_numcommands = 0; server.stat_numconnections = 0; server.stat_expiredkeys = 0; + server.stat_expired_stale_perc = 0; + server.stat_expired_time_cap_reached_count = 0; server.stat_evictedkeys = 0; server.stat_keyspace_misses = 0; server.stat_keyspace_hits = 0; @@ -3132,6 +3134,8 @@ sds genRedisInfoString(char *section) { "sync_partial_ok:%lld\r\n" "sync_partial_err:%lld\r\n" "expired_keys:%lld\r\n" + "expired_stale_perc:%.2f\r\n" + "expired_time_cap_reached_count:%lld\r\n" "evicted_keys:%lld\r\n" "keyspace_hits:%lld\r\n" "keyspace_misses:%lld\r\n" @@ -3156,6 +3160,8 @@ sds genRedisInfoString(char *section) { server.stat_sync_partial_ok, server.stat_sync_partial_err, server.stat_expiredkeys, + server.stat_expired_stale_perc*100, + server.stat_expired_time_cap_reached_count, server.stat_evictedkeys, server.stat_keyspace_hits, server.stat_keyspace_misses, diff --git a/src/server.h b/src/server.h index 5b6074a8..29919f5e 100644 --- a/src/server.h +++ b/src/server.h @@ -950,6 +950,8 @@ struct redisServer { long long stat_numcommands; /* Number of processed commands */ long long stat_numconnections; /* Number of connections received */ long long stat_expiredkeys; /* Number of expired keys */ + double stat_expired_stale_perc; /* Percentage of keys probably expired */ + long long stat_expired_time_cap_reached_count; /* Early expire cylce stops.*/ long long stat_evictedkeys; /* Number of evicted keys (maxmemory) */ long long stat_keyspace_hits; /* Number of successful lookups of keys */ long long stat_keyspace_misses; /* Number of failed lookups of keys */