Redis过期键删除策略、内存淘汰策略

318 阅读6分钟

这是我参与8月更文挑战的第31天,活动详情查看:8月更文挑战

内存回收

Redis是一个完全基于内存操作的中间件,而内存的大小是宝贵且有限的,为了避免内存饱和而影响系统的正常运行,所以在必要时我们需要对内存进行回收,Redis提供了两种方式实现内存的回收,分别为过期键的删除策略内存释放策略

Redis过期键删除策略

我们往Redis里面添加一个键值对时可以指定一个过期时间,当设置过期时间后,Redis是如何对过期键进行处理的?Redis主要通过定期删除、定时删除、惰性删除这三种策略对过期键进行处理。

定期删除

定期删除策略每隔一段时间执行一次删除过期键的操作。

定时删除

定时删除是指在设置键的过期时间时,创建一个定时器,当达到键指定的过期时间时通过定时器去删除键。

惰性删除

惰性删除并不是当达到指定的过期时间时去删除,而是在每次获取键时,都会判断该键是否过期,如果过期则删除,并返回空,没过期,就返回键值。

定时删除

定时删除的优点是对内存友好,通过定时器,当Redis中的键达到指定的过期时间时就会被删除,直接释放了内存。 而它的缺点是对CPU不友好,因为如果Redis中过期键比较多,那么删除这些过期键会占用相当一部分CPU时间。

惰性删除

惰性删除并不是当达到指定的过期时间时去删除,而是在每次获取键时,都会判断该键是否过期,在这种策略下会存在这样一种问题:当Redis中存在冷数据(即该键值对不会被访问到),那么该键就一直存在于内存中不会被删除,对内存不友好。但是惰性删除策略对CPU时间来说是友好的,因为只会在取出键时才对键进行过期检查,删除的目标仅限于当前获取的键,该策略不会在删除其他无关的过期键上花费任何CPU时间。

定期删除

定期删除可以说是惰性删除和定时删除的一种折中策略,定期删除策略每隔一段时间执行一次删除过期键操作,并通过限制删除操作执行的时长和频率来减少删除操作对CPU时间的影响,并且通过定期删除过期键,有效的减少了过期键带来的内存浪费。但是定期删除策略又会存在一种“进退两难”的局面,当指定的删除操作时长,则会占用过多的CPU时间,如果指定的定期删除频率过长,则会导致Redis中过期键无法得到及时的删除,浪费内存。

🚦经过以上对三种过期键删除策略的分析,我们知道了三种删除策略的优缺点,那么Redis采用的是哪种删除策略呢?答案是定期删除+惰性删除配合使用。Redis通过配合使用这两种策略,可以在合理地使用CPU时间和避免浪费内存空间之间取得平衡。

内存淘汰策略

内存淘汰策略是另外一种用来避免内存饱和而影响系统的正常运行的方式,当内存达到maxmemory极限时,使用指定的策略来清理内存中的键值对,以保证新键值对的存入。Redis提供了8种内存淘汰策略,在Redis的配置文件redis.conf中可以看到这几种策略,如下:

# 设置Redis的最大内存
# maxmemory <bytes>

# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
# is reached. You can select one from the following behaviors:
#
# volatile-lru -> Evict using approximated LRU, only keys with an expire set.
# allkeys-lru -> Evict any key using approximated LRU.
# volatile-lfu -> Evict using approximated LFU, only keys with an expire set.
# allkeys-lfu -> Evict any key using approximated LFU.
# volatile-random -> Remove a random key having 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, when there are no suitable keys for
# eviction, Redis will return an error on write operations that require
# more memory. These are usually commands that create new keys, add data or
# modify existing keys. A few examples are: SET, INCR, HSET, LPUSH, SUNIONSTORE,
# SORT (due to the STORE argument), and EXEC (if the transaction includes any
# command that requires memory).
#
# The default is:
# 默认使用的内存淘汰策略为noeviction
# maxmemory-policy noeviction
  1. volatile-lru : 当内存不足以容纳新的键值对时,在设置了过期时间的键中淘汰最近最少使用的键
  2. allkeys-lru : 当内存不足以容纳新的键值对时,从所有的键中选出最近最少使用的键并淘汰
  3. volatile-lfu : 当内存不足以容纳新的键值对时,在设置了过期时间的键中淘汰使用频率最小的键
  4. allkeys-lfu : 当内存不足以容纳新的键值对时,从所有的键中选出使用频率最小的键并淘汰
  5. volatile-random : 当内存不足以容纳新的键值对时,在设置了过期时间的键中随机淘汰某些键
  6. allkeys-random : 当内存不足以容纳新的键值对时,在设置了过期时间的键中随机淘汰某些键
  7. volatile-ttl : 当内存不足以容纳新的键值对时,从所有的键中随机选择某些键进行淘汰
  8. noeviction : 默认策略,不会淘汰数据,新增或者修改数据会抛出异常,但是读操作不受影响

小结

Redis为避免内存饱和而影响系统的正常运行,会对内存进行回收,主要有过期键删除策略内存淘汰策略,过期键删除策略是针对过期键的回收,而内存淘汰策略是在每次执行Redis命令时判断当前Redis是否达到了内存的极限值,如果达到,则使用对应的淘汰策略去处理需要删除的键。

🏁以上就是对Redis过期键删除策略以及内存淘汰策略的简单介绍,如果有错误的地方,还请留言指正,如果觉得本文对你有帮助那就点个赞👍吧😋😻😍

默认标题_动态分割线_2021-07-15-0.gif