Redis 淘汰策略

111 阅读3分钟

过期淘汰策略

Redis的Key可以设置过期时间,当Redis的Key过期了,就会使用过期淘汰策略来删除Key

过期时间数据存在哪

RedisDB的数据结构中有一个存储数据的字典(value是数据),还有一个存储过期时间的字段(value是该key的过期时间)

typedef struct redisDb {
    dict *dict;    /* 数据库键空间,存放着所有的键值对 */
    dict *expires; /* 键的过期时间 */
    ....
} redisDb;

过期淘汰策略有哪些

1. 定时删除:
当时间到达后,由事件处理器立即删除过期的Key。
缺点:这种方式比较耗费CPU资源。

2. 惰性删除:
当时间到达后,不主动删除,每次访问Key的时候,判断是否已过期,如果过期返回Null,并删除该Key,如果没有过期返回数据。
缺点:这种方式删除Key可能不及时。

3. 定期删除:
每隔一段时间随机从数据库中选择一定数量的Key进行检查,并删除其中过期的Key。
缺点:如果检查频率高,比较浪费CPU资源,如果检查频率低,删除Key可能不及时。

Redis过期淘汰策略是什么

Redis使用的是惰性删除+定期删除的方式

内存淘汰策略

当Redis的运行内存超过了Redis设置的最大内存,就会使用内存淘汰策略来删除Key

如何设置Redis最大内存

redis.conf中,通过参数maxmemory <bytes>来设置最大运行内存,不同位数的操作系统,maxmemory的默认值是不同的:

  • 在64位操作系统中,默认值是0,表示没有内存大小限制
  • 在32位操作系统中,默认值是3G,因为32位系统的最大内存为4G,操作系统本身需要一定内存运行,所以Redis的默认值为3G。

Redis内存淘汰策略有哪些

  • noeviction(默认): 不淘汰数据,禁止写入数据
  • volatile-ttl: 优先淘汰将要过期的数据
  • volatile-random: 对于设置了过期时间的数据,随机淘汰
  • volatile-lru: 对于设置了过期时间的数据,淘汰最长未被使用的数据
  • volatile-lfu: 对于设置了过期时间的数据,淘汰访问次数最少的数据
  • allkeys-random: 对于所有数据,随机淘汰
  • allkeys-lru: 对于所有数据,淘汰最长未被使用的数据
  • allkeys-lfu: 对于所有数据,淘汰访问次数最少的数据

LRU和LFU有什么区别

LRU(Least Recently Used)翻译为最近最少使用,淘汰最长未被使用的数据
一般的实现方式是:维护一个链表,每次访问数据将数据移动到链表头部,当进行淘汰时,从尾部开始淘汰。不过频繁的链表移动会影响Redis效率。
Redis的实现方式是:在Redis的对象结构中维护一个访问时间信息,当进行内存淘汰时,随机选择一批数据,淘汰访问时间最早的数据。

LFU(Least Frequently Used)翻译为最不经常使用,淘汰访问次数最少的数据
Redis的实现方式是:在Redis的对象结构中维护访问时间和访问频次两个信息,每次访问key时,计算与上次访问的时间差,时间差值越大,频次衰减就越多。然后使用现在的频次根据一定的概率来增加频次,频次越大,增长越缓慢。