Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redis Internals - LRU Implementation For Sampling

Tags:

redis

lru

Does someone know about the internals of Redis LRU based eviction / deletion.

How does Redis ensure that the older (lesser used) keys are deleted first (in case we do not have volatile keys and we are not setting TTL expiration)?

I know for sure that Redis has a configuration parameter "maxmemory-samples" that governs a sample size that it uses for removing keys - so if you set a sample size of 10 then it samples 10 keys and removes the oldest from amongst these.

What I don't know is whether it sample these key's completely randomly, or does it somehow have a mechanism that allows it to automatically sample from an equivalent of an "older / less used generation"?

like image 843
Gur Kamal Singh Badal Avatar asked Feb 21 '23 22:02

Gur Kamal Singh Badal


2 Answers

This is what I found at antirez.com/post/redis-as-LRU-cache.html - the whole point of using a "sample three" algorithm is to save memory. I think this is much more valuable than precision, especially since this randomized algorithms are rarely well understood. An example: sampling with just three objects will expire 666 objects out of a dataset of 999 with an error rate of only 14% compared to the perfect LRU algorithm. And in the 14% of the remaining there are hardly elements that are in the range of very used elements. So the memory gain will pay for the precision without doubts.

So although Redis samples randomly (implying that this is not actual LRU .. and as such an approximation algorithm), the accuracy is relatively high and increasing the sampling size will further increase this. However, in case someone needs exact LRU (there is zero tolerance for error), then Redis may not be the correct choice.

Architecture ... as they say ... is about tradeoffs .. so use this (Redis LRU) approach to tradeoff accuracy for raw performance.

like image 188
Gur Kamal Singh Badal Avatar answered Mar 02 '23 18:03

Gur Kamal Singh Badal


Since v3.0.0 (2014) the LRU algorithm uses a pool of 15 keys, populated with the best candidates out of the different samplings of N keys (where N is defined by maxmemory-samples).

Every time a key needs to be evicted, N new keys are selected randomly and checked against the pool. If they're better candidates (older keys), they're added in it, while the worst candidates (most recent keys) are taken out, keeping the pool at a constant size of 15 keys.

At the end of the round, the best eviction candidate is selected from the pool.

Source: Code and comments in evict.c file from Redis source code

like image 31
Elena Kolevska Avatar answered Mar 02 '23 17:03

Elena Kolevska