配置redis以首先逐步驱逐旧数据

Ike*_*ker 17 caching redis

我在redis中存储了一堆实时数据.我在所有按键上设置了14400秒(4小时)的TTL.我已经将maxmemory设置为10G,目前没有足够的空间来容纳4小时的内存数据,而且我没有使用虚拟内存,因此redis在数据到期之前将其逐出.

我很好用redis驱逐数据,但我希望它首先驱逐最旧的数据.所以,即使我没有整整4个小时的数据,至少我可以有一个不带间隙的某一范围的数据(3小时,2小时等).我试图通过设置来实现这一目标maxmemory-policy=volatile-ttl,因为他们认为最旧的密钥会被驱逐,因为它们都具有相同的TTL,但它不是那样工作的.似乎redis有点随意地驱逐数据,所以最终我的数据存在差距.例如,今天2012-01-25T13:00的数据在2012-01-25T12:00之前的数据被逐出.

是否可以将redis配置为始终首先逐出旧数据?

以下是我的redis.cnf文件中的相关行.如果您想要查看更多的配置,请告诉我们:

maxmemory 10gb
maxmemory-policy volatile-ttl
vm-enabled no
Run Code Online (Sandbox Code Playgroud)

Did*_*zia 31

AFAIK,无法将Redis配置为始终首先逐出旧数据.

在maxmemory-policy中选择*-ttl或*-lru选项时,Redis不使用精确算法来选择要删除的键.精确算法在内存中需要额外的列表(用于*-lru)或额外的堆(用于*-ttl),并使用普通的Redis字典数据结构进行交叉引用.就内存消耗而言,这将是昂贵的.

利用当前机制,驱逐发生在主事件循环中(即,在执行每个命令之前在每个循环迭代处检查潜在的驱逐).在内存回到maxmemory限制之前,Redis随机选择n个密钥的样本,并选择最多空闲的一个(对于*-lru)或最接近其到期限制的一个(对于*-ttl).默认情况下,只考虑3个样本.结果是不确定的.

提高此算法准确性并缓解问题的一种方法是增加所考虑样本的数量(配置文件中的maxmemory-samples参数).不要设置得太高,因为它会占用一些CPU.它是逐出精确度和CPU消耗之间的权衡.

现在,如果您确实需要一致的行为,一种解决方案是在Redis之上实现您自己的驱逐机制.例如,您可以添加一个列表(对于不可更新的键)或一个有序集(对于可更新的键),以便跟踪应首先被驱逐的键.然后,添加一个守护程序,其目的是定期检查(使用INFO)内存消耗并查询列表/有序集的项以删除相关键.

请注意其他缓存系统有自己的方法来处理这个问题.例如,对于memcached,每个slab有一个LRU结构(取决于对象大小),因此驱逐顺序也不准确(尽管在实践中比Redis更具确定性).

  • 多么彻底的答案! (2认同)