Redis 的过期策略和内存淘汰机制

Redis 如何处理过期数据的

对于已经过期的数据,Redis 将使用两种策略来删除这些过期键,它们分别是惰性删除和定期删除。

惰性删除

惰性删除是指 Redis 服务器不主动删除过期的键值,而是当访问键值时,再检查当前的键值是否过期,如果过期则执行删除并返回 null 给客户端;如果没过期则正常返回值信息给客户端。

它的优点是不会浪费太多的系统资源,只是在每次访问时才检查键值是否过期。缺点是删除过期键不及时,造成了一定的空间浪费。

定期删除

定期删除是指 Redis 服务器每隔一段时间会检查一下数据库,看看是否有过期键可以被清除。

默认情况下 Redis 定期检查的频率是每秒扫描 10 次,用于定期清除过期键。当然此值还可以通过配置文件进行设置,在 redis.conf 中修改配置“hz”即可,默认的值为“hz 10”。

定期删除的扫描并不是遍历所有的键值对,这样的话比较费时且太消耗系统资源。Redis 服务器采用的是随机抽取形式,每次从过期字典中,取出 20 个键进行过期检测,过期字典中存储的是所有设置了过期时间的键值对。如果这批随机检查的数据中有 25% 的比例过期,那么会再抽取 20 个随机键值进行检测和删除,并且会循环执行这个流程,直到抽取的这批数据中过期键值小于 25%,此次检测才算完成。

Redis 内存淘汰策略

内存淘汰算法主要包含两种:LRU 淘汰算法和 LFU 淘汰算法。
LRU( Least Recently Used,最近最少使用)淘汰算法:是一种常用的页面置换算法,也就是说最久没有使用的缓存将会被淘汰。

LRU 是基于链表结构实现的,链表中的元素按照操作顺序从前往后排列,最新操作的键会被移动到表头,当需要进行内存淘汰时,只需要删除链表尾部的元素即可。

LFU(Least Frequently Used,最不常用的)淘汰算法:最不常用的算法是根据总访问次数来淘汰数据的,它的核心思想是“如果数据过去被访问多次,那么将来被访问的频率也更高”。

LFU 相对来说比 LRU 更“智能”,因为它解决了使用频率很低的缓存,只是最近被访问了一次就不会被删除的问题。如果是使用 LRU 类似这种情况数据是不会被删除的,而使用 LFU 的话,这个数据就会被删除。

内存淘汰和过期策略是完全不同的两个概念,内存淘汰策略是当内存不够用时才会触发的一种机制,它在 Redis 4.0 之后提供了 8 种内存淘汰策略,这些淘汰策略主要使用了近 LRU 淘汰算法和 LFU 淘汰算法。
LRU( Least Recently Used,最近最少使用)淘汰算法:是一种常用的页面置换算法,也就是说最久没有使用的缓存将会被淘汰。

noeviction:不淘汰任何数据,当内存不足时,执行缓存新增操作会报错,它是 Redis 默认内存淘汰策略。
allkeys-lru:淘汰整个键值中最久未使用的键值。
allkeys-random:随机淘汰任意键值。
volatile-lru:淘汰所有设置了过期时间的键值中最久未使用的键值。
volatile-random:随机淘汰设置了过期时间的任意键值。
volatile-ttl:优先淘汰更早过期的键值。
volatile-lfu,淘汰所有设置了过期时间的键值中最少使用的键值。
allkeys-lfu,淘汰整个键值中最少使用的键值。

可以使用 config get maxmemory-policy 命令,来查看当前 Redis 的内存淘汰策略

内存淘汰策略可以通过配置文件来修改,redis.conf 对应的配置项是“maxmemory-policy noeviction”,只需要把它修改成我们需要设置的类型即可。

需要注意的是,如果使用修改 redis.conf 的方式,当设置完成之后需要重启 Redis 服务器才能生效。

还有另一种简单的修改内存淘汰策略的方式,我们可以使用命令行工具输入“config set maxmemory-policy noeviction”来修改内存淘汰的策略,这种修改方式的好处是执行成功之后就会生效,无需重启 Redis 服务器。但它的坏处是不能持久化内存淘汰策略,每次重启 Redis 服务器之后设置的内存淘汰策略就会丢失。

Redis 内存淘汰策略使用了 LFU 和近 LRU 的淘汰算法,具体使用哪种淘汰算法,要看服务器是如何设置内存淘汰策略的,也就是要看“maxmemory-policy”的值是如何设置的。

你可能感兴趣的:(Redis 的过期策略和内存淘汰机制)