Support TTL stats with the new expire datastructure
Former-commit-id: 271df3dad4f55f20177a8a9a065778f4943835f1
This commit is contained in:
parent
d050d20a9f
commit
d58b2575e5
15
src/db.cpp
15
src/db.cpp
@ -1122,11 +1122,13 @@ int dbSwapDatabases(int id1, int id2) {
|
||||
db1->setexpire = db2->setexpire;
|
||||
db1->expireitr = db2->expireitr;
|
||||
db1->avg_ttl = db2->avg_ttl;
|
||||
db1->last_expire_set = db2->last_expire_set;
|
||||
|
||||
db2->pdict = aux.pdict;
|
||||
db2->setexpire = aux.setexpire;
|
||||
db2->expireitr = aux.expireitr;
|
||||
db2->avg_ttl = aux.avg_ttl;
|
||||
db2->last_expire_set = aux.last_expire_set;
|
||||
|
||||
/* Now we need to handle clients blocked on lists: as an effect
|
||||
* of swapping the two DBs, a client that was waiting for list
|
||||
@ -1220,6 +1222,19 @@ void setExpire(client *c, redisDb *db, robj *key, long long when) {
|
||||
expireEntry e((sds)dictGetKey(kde), when);
|
||||
((robj*)dictGetVal(kde))->SetFExpires(true);
|
||||
|
||||
/* Update TTL stats (exponential moving average) */
|
||||
/* Note: We never have to update this on expiry since we reduce it by the current elapsed time here */
|
||||
long long now = g_pserver->mstime;
|
||||
db->avg_ttl -= (now - db->last_expire_set); // reduce the TTL by the time that has elapsed
|
||||
if (db->setexpire->empty())
|
||||
db->avg_ttl = 0;
|
||||
else
|
||||
db->avg_ttl -= db->avg_ttl / db->setexpire->size(); // slide one entry out the window
|
||||
if (db->avg_ttl < 0)
|
||||
db->avg_ttl = 0; // TTLs are never negative
|
||||
db->avg_ttl += (double)(when-now) / (db->setexpire->size()+1); // add the new entry
|
||||
db->last_expire_set = now;
|
||||
|
||||
db->setexpire->insert(e);
|
||||
|
||||
int writable_slave = listLength(g_pserver->masters) && g_pserver->repl_slave_ro == 0;
|
||||
|
@ -155,8 +155,8 @@ void activeExpireCycle(int type) {
|
||||
/* If there is nothing to expire try next DB ASAP. */
|
||||
if (db->setexpire->empty())
|
||||
{
|
||||
// TODO: Compute db->avg_ttl somewhere... but probably not here
|
||||
db->avg_ttl = 0;
|
||||
db->last_expire_set = now;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2926,6 +2926,7 @@ void initServer(void) {
|
||||
g_pserver->db[j].watched_keys = dictCreate(&keylistDictType,NULL);
|
||||
g_pserver->db[j].id = j;
|
||||
g_pserver->db[j].avg_ttl = 0;
|
||||
g_pserver->db[j].last_expire_set = 0;
|
||||
g_pserver->db[j].defrag_later = listCreate();
|
||||
}
|
||||
|
||||
@ -4566,10 +4567,17 @@ sds genRedisInfoString(const char *section) {
|
||||
|
||||
keys = dictSize(g_pserver->db[j].pdict);
|
||||
vkeys = g_pserver->db[j].setexpire->size();
|
||||
|
||||
// Adjust TTL by the current time
|
||||
g_pserver->db[j].avg_ttl -= (g_pserver->mstime - g_pserver->db[j].last_expire_set);
|
||||
if (g_pserver->db[j].avg_ttl < 0)
|
||||
g_pserver->db[j].avg_ttl = 0;
|
||||
g_pserver->db[j].last_expire_set = g_pserver->mstime;
|
||||
|
||||
if (keys || vkeys) {
|
||||
info = sdscatprintf(info,
|
||||
"db%d:keys=%lld,expires=%lld,avg_ttl=%lld\r\n",
|
||||
j, keys, vkeys, g_pserver->db[j].avg_ttl);
|
||||
j, keys, vkeys, static_cast<long long>(g_pserver->db[j].avg_ttl));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -844,7 +844,8 @@ typedef struct redisDb {
|
||||
dict *ready_keys; /* Blocked keys that received a PUSH */
|
||||
dict *watched_keys; /* WATCHED keys for MULTI/EXEC CAS */
|
||||
int id; /* Database ID */
|
||||
long long avg_ttl; /* Average TTL, just for stats */
|
||||
long long last_expire_set; /* when the last expire was set */
|
||||
double avg_ttl; /* Average TTL, just for stats */
|
||||
list *defrag_later; /* List of key names to attempt to defrag one by one, gradually. */
|
||||
} redisDb;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user