有人知道基于Redis LRU的驱逐/删除的内部结构。
Redis如何确保首先删除较旧(较少使用)的密钥(如果我们没有易失密钥并且我们没有设置TTL过期)?
我确信Redis有一个配置参数“maxmemory-samples”来管理它用于删除键的样本大小 - 所以如果你设置一个10的样本大小,它会取样10个密钥并删除其中的最老的这些
我不知道的是它是否完全随机地对这些密钥进行采样,或者它是否有某种机制允许它从相当于“较旧/较少使用的代”中自动采样?
答案 0 :(得分:7)
这是我在antirez.com/post/redis-as-LRU-cache.html找到的 - 使用“样本三”算法的全部目的是节省内存。我认为这比精确度更有价值,特别是因为这种随机算法很少被很好地理解。例如:仅使用三个对象进行采样将使999数据集中的666个对象失效,与完美LRU算法相比,错误率仅为14%。并且在剩余的14%中,几乎没有元素属于非常常用的元素。因此,记忆增益将毫无疑问地为精确度付出代价。
因此,尽管Redis随机采样(暗示这不是实际的LRU ......并且作为这样的近似算法),但精度相对较高,并且增加采样大小将进一步增加这一点。但是,如果有人需要精确的LRU(误差容差为零),那么Redis可能不是正确的选择。
架构......正如他们所说......是关于权衡的......所以使用这种(Redis LRU)方法来获得原始性能的权衡准确性。
答案 1 :(得分:0)
自v3.0.0(2014)起,LRU算法使用15个密钥池,其中填充了N个密钥的不同采样中的最佳候选者(其中N由maxmemory-samples
定义)。
每次需要移出密钥时,都会随机选择N个新密钥并对照池进行检查。如果它们是更好的候选者(旧密钥),则将它们添加到其中,而最差的候选者(最新密钥)则被删除,以使池保持15个密钥的恒定大小。
在一轮结束时,从池中选择最佳驱逐候选者。
来源:Code and comments in evict.c file来自Redis源代码