mirror of
https://github.com/fluencelabs/redis
synced 2025-03-19 17:10:50 +00:00
RDB: Ability to save LFU/LRU info.
This is a big win for caching use cases, since on reloading Redis will still have some idea about what is worth to evict and what not. However this only solves part of the problem because the information is only partially propagated to slaves (on write operations). Reads will not affect slaves LFU and LRU counters, so after a failover the eviction decisions are kinda random until keys start to collect some aging/freq info. However since new slaves are initially populated via RDB file transfer, this means that if we spin up a new slave from a master, and perform an immediate manual failover (for instance in order to upgrade the master), the slave will have eviction informations to use for some time. The LFU/LRU info is persisted only if the maxmemory policy is set to one of the relevant type, even if no actual "maxmemory" memory limit is set.
This commit is contained in:
parent
6614361615
commit
d7a5c0eb71
23
src/rdb.c
23
src/rdb.c
@ -973,6 +973,9 @@ size_t rdbSavedObjectLen(robj *o) {
|
|||||||
int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val,
|
int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val,
|
||||||
long long expiretime, long long now)
|
long long expiretime, long long now)
|
||||||
{
|
{
|
||||||
|
int savelru = server.maxmemory_policy & MAXMEMORY_FLAG_LRU;
|
||||||
|
int savelfu = server.maxmemory_policy & MAXMEMORY_FLAG_LFU;
|
||||||
|
|
||||||
/* Save the expire time */
|
/* Save the expire time */
|
||||||
if (expiretime != -1) {
|
if (expiretime != -1) {
|
||||||
/* If this key is already expired skip it */
|
/* If this key is already expired skip it */
|
||||||
@ -981,6 +984,26 @@ int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val,
|
|||||||
if (rdbSaveMillisecondTime(rdb,expiretime) == -1) return -1;
|
if (rdbSaveMillisecondTime(rdb,expiretime) == -1) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Save the LRU info. */
|
||||||
|
if (savelru) {
|
||||||
|
int idletime = estimateObjectIdleTime(val);
|
||||||
|
idletime /= 1000; /* Using seconds is enough and requires less space.*/
|
||||||
|
if (rdbSaveType(rdb,RDB_OPCODE_IDLE) == -1) return -1;
|
||||||
|
if (rdbSaveLen(rdb,idletime) == -1) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save the LFU info. */
|
||||||
|
if (savelfu) {
|
||||||
|
uint8_t buf[1];
|
||||||
|
buf[0] = LFUDecrAndReturn(val);
|
||||||
|
/* We can encode this in exactly two bytes: the opcode and an 8
|
||||||
|
* bit counter, since the frequency is logarithmic with a 0-255 range.
|
||||||
|
* Note that we do not store the halving time because to reset it
|
||||||
|
* a single time when loading does not affect the frequency much. */
|
||||||
|
if (rdbSaveType(rdb,RDB_OPCODE_FREQ) == -1) return -1;
|
||||||
|
if (rdbWriteRaw(rdb,buf,1) == -1) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Save type, key, value */
|
/* Save type, key, value */
|
||||||
if (rdbSaveObjectType(rdb,val) == -1) return -1;
|
if (rdbSaveObjectType(rdb,val) == -1) return -1;
|
||||||
if (rdbSaveStringObject(rdb,key) == -1) return -1;
|
if (rdbSaveStringObject(rdb,key) == -1) return -1;
|
||||||
|
14
src/rdb.h
14
src/rdb.h
@ -97,12 +97,14 @@
|
|||||||
#define rdbIsObjectType(t) ((t >= 0 && t <= 7) || (t >= 9 && t <= 15))
|
#define rdbIsObjectType(t) ((t >= 0 && t <= 7) || (t >= 9 && t <= 15))
|
||||||
|
|
||||||
/* Special RDB opcodes (saved/loaded with rdbSaveType/rdbLoadType). */
|
/* Special RDB opcodes (saved/loaded with rdbSaveType/rdbLoadType). */
|
||||||
#define RDB_OPCODE_AUX 250
|
#define RDB_OPCODE_IDLE 248 /* LRU idle time. */
|
||||||
#define RDB_OPCODE_RESIZEDB 251
|
#define RDB_OPCODE_FREQ 249 /* LFU frequency. */
|
||||||
#define RDB_OPCODE_EXPIRETIME_MS 252
|
#define RDB_OPCODE_AUX 250 /* RDB aux field. */
|
||||||
#define RDB_OPCODE_EXPIRETIME 253
|
#define RDB_OPCODE_RESIZEDB 251 /* Hash table resize hint. */
|
||||||
#define RDB_OPCODE_SELECTDB 254
|
#define RDB_OPCODE_EXPIRETIME_MS 252 /* Expire time in milliseconds. */
|
||||||
#define RDB_OPCODE_EOF 255
|
#define RDB_OPCODE_EXPIRETIME 253 /* Old expire time in seconds. */
|
||||||
|
#define RDB_OPCODE_SELECTDB 254 /* DB number of the following keys. */
|
||||||
|
#define RDB_OPCODE_EOF 255 /* End of the RDB file. */
|
||||||
|
|
||||||
/* Module serialized values sub opcodes */
|
/* Module serialized values sub opcodes */
|
||||||
#define RDB_MODULE_OPCODE_EOF 0 /* End of module value. */
|
#define RDB_MODULE_OPCODE_EOF 0 /* End of module value. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user