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->setexpire = db2->setexpire;
|
||||||
db1->expireitr = db2->expireitr;
|
db1->expireitr = db2->expireitr;
|
||||||
db1->avg_ttl = db2->avg_ttl;
|
db1->avg_ttl = db2->avg_ttl;
|
||||||
|
db1->last_expire_set = db2->last_expire_set;
|
||||||
|
|
||||||
db2->pdict = aux.pdict;
|
db2->pdict = aux.pdict;
|
||||||
db2->setexpire = aux.setexpire;
|
db2->setexpire = aux.setexpire;
|
||||||
db2->expireitr = aux.expireitr;
|
db2->expireitr = aux.expireitr;
|
||||||
db2->avg_ttl = aux.avg_ttl;
|
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
|
/* Now we need to handle clients blocked on lists: as an effect
|
||||||
* of swapping the two DBs, a client that was waiting for list
|
* 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);
|
expireEntry e((sds)dictGetKey(kde), when);
|
||||||
((robj*)dictGetVal(kde))->SetFExpires(true);
|
((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);
|
db->setexpire->insert(e);
|
||||||
|
|
||||||
int writable_slave = listLength(g_pserver->masters) && g_pserver->repl_slave_ro == 0;
|
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 there is nothing to expire try next DB ASAP. */
|
||||||
if (db->setexpire->empty())
|
if (db->setexpire->empty())
|
||||||
{
|
{
|
||||||
// TODO: Compute db->avg_ttl somewhere... but probably not here
|
|
||||||
db->avg_ttl = 0;
|
db->avg_ttl = 0;
|
||||||
|
db->last_expire_set = now;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2926,6 +2926,7 @@ void initServer(void) {
|
|||||||
g_pserver->db[j].watched_keys = dictCreate(&keylistDictType,NULL);
|
g_pserver->db[j].watched_keys = dictCreate(&keylistDictType,NULL);
|
||||||
g_pserver->db[j].id = j;
|
g_pserver->db[j].id = j;
|
||||||
g_pserver->db[j].avg_ttl = 0;
|
g_pserver->db[j].avg_ttl = 0;
|
||||||
|
g_pserver->db[j].last_expire_set = 0;
|
||||||
g_pserver->db[j].defrag_later = listCreate();
|
g_pserver->db[j].defrag_later = listCreate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4566,10 +4567,17 @@ sds genRedisInfoString(const char *section) {
|
|||||||
|
|
||||||
keys = dictSize(g_pserver->db[j].pdict);
|
keys = dictSize(g_pserver->db[j].pdict);
|
||||||
vkeys = g_pserver->db[j].setexpire->size();
|
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) {
|
if (keys || vkeys) {
|
||||||
info = sdscatprintf(info,
|
info = sdscatprintf(info,
|
||||||
"db%d:keys=%lld,expires=%lld,avg_ttl=%lld\r\n",
|
"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 *ready_keys; /* Blocked keys that received a PUSH */
|
||||||
dict *watched_keys; /* WATCHED keys for MULTI/EXEC CAS */
|
dict *watched_keys; /* WATCHED keys for MULTI/EXEC CAS */
|
||||||
int id; /* Database ID */
|
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. */
|
list *defrag_later; /* List of key names to attempt to defrag one by one, gradually. */
|
||||||
} redisDb;
|
} redisDb;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user