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

joe*_*von 33 caching redis

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

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

我希望有很多没有TTL的数据,并希望确保让Redis知道什么过期是安全的.

Did*_*zia 43

我不认为这个问题与虚拟内存管理有关,而是更多关于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
Run Code Online (Sandbox Code Playgroud)

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

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

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


Gur*_*dal 8

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

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

maxmemory-samples 10

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