Redis内存回收策略

概述

redis也会因为内存不足而产生错误 , 也可能因为回收过久而导致系统长期的停顿,因此掌握执行回收策略十分有必要。在 redis 的配置文件中,当 redis 的内存达到规定的最大值时,允许配置 6 种策略中的一种进行淘汰键值,并且将一些键值对进行回收。

maxmemory-policy 参数

# set a memory usage limit to the specified amount of bytes.
# when the memory limit is reached redis will try to remove keys
# according to the eviction policy selected (see maxmemory-policy).
#
# if redis can't remove keys according to the policy, or if the policy is
# set to 'noeviction', redis will start to reply with errors to commands
# that would use more memory, like set, lpush, and so on, and will continue
# to reply to read-only commands like get.
#
# this option is usually useful when using redis as an lru or lfu cache, or to
# set a hard memory limit for an instance (using the 'noeviction' policy).
#
# warning: if you have slaves attached to an instance with maxmemory on,
# the size of the output buffers needed to feed the slaves are subtracted
# from the used memory count, so that network problems / resyncs will
# not trigger a loop where keys are evicted, and in turn the output
# buffer of slaves is full with dels of keys evicted triggering the deletion
# of more keys, and so forth until the database is completely emptied.
#
# in short... if you have slaves attached it is suggested that you set a lower
# limit for maxmemory so that there is some free ram on the system for slave
# output buffers (but this is not needed if the policy is 'noeviction').
#
# maxmemory <bytes>

# maxmemory policy: how redis will select what to remove when maxmemory
# is reached. you can select among five behaviors:
#
# volatile-lru -> evict using approximated lru among the keys with an expire set.
# allkeys-lru -> evict any key using approximated lru.
# volatile-lfu -> evict using approximated lfu among the keys with an expire set.
# allkeys-lfu -> evict any key using approximated lfu.
# volatile-random -> remove a random key among the ones 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 evict anything, just return an error on write operations.
#
# lru means least recently used
# lfu means least frequently used
#
# both lru, lfu and volatile-ttl are implemented using approximated
# randomized algorithms.
#
# note: with any of the above policies, redis will return an error on write
#       operations, when there are no suitable keys for eviction.
#
#       at the date of writing these 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 noeviction

主动清理策略

主动清理策略在redis 4.0 之前一共实现了 6 种内存淘汰策略,在 4.0 之后,又增加了 2 种策略,总共8种:

【针对设置了过期时间的key做处理】

  • volatile-ttl:在筛选时,会针对设置了过期时间的键值对,根据过期时间的先后进行删除,越早过期的越先被删除。
  • volatile-random:就像它的名称一样,在设置了过期时间的键值对中,进行随机删除。
  • volatile-lru:会使用 lru 算法筛选设置了过期时间的键值对删除。
  • volatile-lfu:会使用 lfu 算法筛选设置了过期时间的键值对删除

【 针对所有的key做处理】

  • allkeys-random:从所有键值对中随机选择并删除数据。
  • allkeys-lru:使用 lru 算法在所有数据中进行筛选删除。
  • allkeys-lfu:使用 lfu 算法在所有数据中进行筛选删除。

【 不处理 (默认)】

noeviction:不会剔除任何数据,拒绝所有写入操作并返回客户端错误信息”(error) oom command not allowed when used memory”,此时redis只响应读操作。

redis 在默认情况下会采用 noeviction 策略。换句话说,如果内存己满 , 则不再提供写入操作 , 而只提供读取操作 。 显然这往往并不能满足我们的要求,因为对于互联网系统而言 , 常常会涉及数以百万甚至更多的用户 , 所以往往需要设置回收策略。

策略选择

lru 算法(least recently used,最近最少使用):淘汰很久没被访问过的数据,以最近一次访问时间作为参考

lfu 算法(least frequently used,最不经常使用):淘汰最近一段时间被访问次数最少的数据,以次数作为参考

需要指出的是 : lru 算法或者 ttl 算法都是不是很精确算法,而是一个近似的算法。 redis 不会通过对全部的键值对进行比较来确定最精确的时间值,从而确定删除哪个键值对 , 因为这将消耗太多的时间 , 导致回收垃圾执行的时间太长 , 造成服务停顿.

当存在热点数据时,lru的效率很好,但偶发性的、周期性的批量操作会导致lru命中率急剧下降,缓存污染情况比较严重。这时使用lfu可能更好点

根据自身业务类型,配置好maxmemory-policy(默认是noeviction),推荐使用volatile-lru。

maxmemory-sample

而在redis 的默认配置文件中 , 存在着参数 maxmemory-sample

# lru, lfu and minimal ttl algorithms are not precise algorithms but approximated
# algorithms (in order to save memory), so you can tune it for speed or
# accuracy. for default redis will check five keys and pick the one that was
# used less recently, you can change the sample size using the following
# configuration directive.
#
# the default of 5 produces good enough results. 10 approximates very closely
# true lru but costs more cpu. 3 is faster but not very accurate.
#
# maxmemory-samples 5

当设置 maxmemory-samples越大,则 redis 删除的就越精确,但是与此同时带来不利的是, redis 也就需要花更多的时去计算匹配更为精确的值 。

回收超时策略的缺点是必须指明超时的键值对 ,这会给程序开发带来一些设置超时的代码,无疑增加了开发者的工作量。

对所有的键值对进行回收,有可能把正在使用的键值对删掉,增加了存储的不稳定性。

对于垃圾回收的策略,还需要注意的是回收的时间,因为在 redis 对垃圾的回收期间, 会造成系统缓慢。

因此,控制其回收时间有一定好处,只是这个时间不能过短或过长。过短则会造成回收次数过于频繁,过长则导致系统单次垃圾回收停顿时间过长,都不利于系统的稳定性,这些都需要设计者在实际的工作中进行思考 。

如果不设置最大内存,当 redis 内存超出物理内存限制时,内存的数据会开始和磁盘产生频繁的交换 (swap),会让 redis 的性能急剧下降。

到此这篇关于 redis内存回收策略的文章就介绍到这了,更多相关 redis内存回收内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com! 

(0)
上一篇 2022年3月21日
下一篇 2022年3月21日

相关推荐