当RAM开始填满时,Redis如何工作?

时间:2011-12-28 05:56:35

标签: caching redis

我可能完全离开了,但是我对缓存存储在开始添加持久性功能之前的工作方式的理解是,项目会根据他们的ttl过期。如果商店开始填满可用的RAM,他们每个人都会有他们的算法来使商店中最不重要的“钥匙”到期。

现在我读到Redis具有持久性功能。但你可以把它们关掉。假设你关闭了持久性,当RAM填满时会发生什么? Redis如何决定过期的内容?

我希望在没有TTL的情况下拥有大量数据,并希望确保让Redis知道要过期的内容是安全的。

4 个答案:

答案 0 :(得分:42)

我不认为这个问题与虚拟内存管理有关,而是与Redis中项目的到期有关,这是一个完全不同的主题。

与memcached相反,Redis不仅仅是一个缓存。因此,用户应该使用各种机制来选择项目驱逐策略。您可以驱逐所有物品,或仅驱逐其中的一部分。

应在配置文件中选择一般策略,其中包含maxmemory和maxmemory-policy参数,如下所述:

# Don't use more memory than the specified amount of bytes.
# When the memory limit is reached Redis will try to remove keys with an
# EXPIRE set. It will try to start freeing keys that are going to expire
# in little time and preserve keys with a longer time to live.
# Redis will also try to remove objects from free lists if possible.
#
# If all this fails, Redis will start to reply with errors to commands
# that will use more memory, like SET, LPUSH, and so on, and will continue
# to reply to most read-only commands like GET.
#
# WARNING: maxmemory can be a good idea mainly if you want to use Redis as a
# 'state' server or cache, not as a real DB. When Redis is used as a real
# database the memory usage will grow over the weeks, it will be obvious if
# it is going to use too much memory in the long run, and you'll have the time
# to upgrade. With maxmemory after the limit is reached you'll start to get
# errors for write operations, and this may even lead to DB inconsistency.
#
maxmemory <bytes>

# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
# is reached? You can select among five behavior:
#
# volatile-lru -> remove the key with an expire set using an LRU algorithm
# allkeys-lru -> remove any key accordingly to the LRU algorithm
# volatile-random -> remove a random key with an expire set
# allkeys->random -> remove a random key, any key
# volatile-ttl -> remove the key with the nearest expire time (minor TTL)
# noeviction -> don't expire at all, just return an error on write operations
#
# Note: with all the kind of policies, Redis will return an error on write
#       operations, when there are not suitable keys for eviction.
#
#       At the date of writing this commands are: set setnx setex append
#       incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd
#       sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby
#       zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby
#       getset mset msetnx exec sort
#
# The default is:
#
maxmemory-policy volatile-lru

# LRU and minimal TTL algorithms are not precise algorithms but approximated
# algorithms (in order to save memory), so you can select as well the sample
# size to check. For instance for default Redis will check three keys and
# pick the one that was used less recently, you can change the sample size
# using the following configuration directive.
#
maxmemory-samples 3

然后可以使用以下命令设置单个项目到期: EXPIRE EXPIREAT 每个项目的到期属性对volatile- *策略很有用。 也可以使用PERSIST删除到期时间。

expiration属性会增加一些内存开销,因此只有在需要时才应该使用它。

最后,值得一提的是,对象的一部分不能过期,只有整个对象本身。例如,与密钥对应的整个列表或集合可能已过期,但单个列表或集合项目不能过期。

答案 1 :(得分:8)

Didier说明了如何做到这一点是正确的。只是指出一些额外的元素(其中一个似乎从他的帖子中省略):

  1. 指定占用该节点上大部分可用内存的最大内存大小(保留一些用于操作系统和其他进程以及一些缓冲区)。这将确保内容永远不会被分页,因此操作是快速的。
    1. 如果您没有通过应用程序设置TTL /过期密钥,那么使用“allkeys-lru”方法很重要。否则,Redis不会过期(因为没有任何键是易失性的),并且一旦所有内存都用完了就会开始出错 - 基本上你将无法再进行任何设置操作。
    2. 使用LRU移除密钥时,请务必设置以下设置:
  2. maxmemory-samples 10

    这是Redis将采用的样本数,然后从这些样本中删除LRU密钥。默认值为3,但出于所有实际目的,这个值太低 - 可能意味着旧密钥可能仍然存在。将此设置得太高将是Redis的开销。 在设置之前,您可能需要稍微尝试此设置。我们使用的值为10。

答案 2 :(得分:3)

请阅读Redis文档中的Virtual Memory章节。 相关部分:

  

vm-max-memory设置   vm-max-memory设置指定在开始交换磁盘上的值之前Redis可以使用的内存量。

     

基本上,如果未达到此内存限制,则不会交换任何对象,Redis将照常处理内存中的所有对象。但是,一旦达到此限制,就会换出足够的对象以使内存恢复到极限之下。

     

交换的对象主要是具有最高“年龄”的对象(即自未使用以来的秒数),但对象的“可交换性”也与其大小的对数成正比。记忆。因此,虽然较旧的对象是首选,但较大的对象在大约相同的年龄时首先被换出。

     

警告:由于无法换出密钥,如果单独使用密钥的空间超出限制,Redis将无法遵守vm-max-memory设置。      

此设置的最佳值是足够的RAM来保存数据的“工作集”。实际上,只要给Redis尽可能多的内存,交换就会更好。

<强>更新 至于Redis 2.4(似乎Redis站点中的官方文档没有更新到该版本),不建议使用VM。

redis.conf说:

### WARNING! Virtual Memory is deprecated in Redis 2.4
### The use of Virtual Memory is strongly discouraged.

答案 3 :(得分:2)

设置TTL(并让Redis为您处理到期日期)或使用您自己的老化数据发布您的项目,也许存储为(时间戳,密钥)元组的ZSET,您可以根据这些元组执行自己的缓存清理自己的需要。