概述
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!