内存淘汰算法_Redis数据淘汰算法

众所周知,Redis的所有数据都存储在内存中,但是内存是一种有限的资源,所以为了防止Redis无限制的使用内存,在启动Redis时可以通过配置项 maxmemory 来指定其最大能使用的内存容量。例如可以通过以下配置来设置Redis最大能使用 1G 内存:

maxmemory 1G

当Redis使用的内存超过配置的 maxmemory 时,便会触发数据淘汰策略。Redis提供了多种数据淘汰的策略,如下:

  • volatile-lru: 最近最少使用算法,从设置了过期时间的键中选择空转时间最长的键值对清除掉

  • volatile-lfu: 最近最不经常使用算法,从设置了过期时间的键中选择某段时间之内使用频次最小的键值对清除掉

  • volatile-ttl: 从设置了过期时间的键中选择过期时间最早的键值对清除

  • volatile-random: 从设置了过期时间的键中,随机选择键进行清除

  • allkeys-lru: 最近最少使用算法,从所有的键中选择空转时间最长的键值对清除

  • allkeys-lfu: 最近最不经常使用算法,从所有的键中选择某段时间之内使用频次最少的键值对清除

  • allkeys-random: 所有的键中,随机选择键进行删除

  • noeviction: 不做任何的清理工作,在redis的内存超过限制之后,所有的写入操作都会返回错误;但是读操作都能正常的进行

可以在启动Redis时,通过配置项 maxmemory_policy 来指定要使用的数据淘汰策略。例如要使用 volatile-lru 策略可以通过以下配置来指定:

maxmemory_policy volatile-lru

LRU算法

LRU是 Least Recently Used 的缩写,即最近最少使用,很多缓存系统都使用此算法作为淘汰策略。

最简单的实现方式就是把所有缓存通过一个链表连接起来,新创建的缓存添加到链表的头部,如果有缓存被访问了,就把缓存移动到链表的头部。由于被访问的缓存会移动到链表的头部,所以没有被访问的缓存会随着时间的推移移动的链表的尾部,淘汰数据时只需要从链表的尾部开始即可。下图展示了这个过程: 5f09731564431a5a5beb4bfd6a576ba3.png

Redis的LRU算法

Redis使用了结构体 robj 来存储缓存对象,而 robj 结构有个名为 lru 的字段,用于记录缓存对象最后被访问的时间,Redis就是以 lru 字段的值作为淘汰依据。robj 结构如下:

typedef struct redisObject {
    
...unsigned lru:24;
...
} robj;

当缓存对象被访问时,便会更新此字段的值。代码如下:

robj *lookupKey(redisDb *db, robj *key, int flags) {
    
dictEntry *de = dictFind(db->dict,key->ptr);if (de) {
robj *val = dictGetVal(de);/* Update the access time for the ageing algorithm. * Don't do it if we have a saving child, as this will trigger * a copy on write madness. */if (server.rdb_child_pid == -1 &&
server.aof_child_pid == -1 &&
!(flags & LOOKUP_NOTOUCH))
{ if (server.maxmemory_policy & MAXMEMORY_FLAG_LFU) { updateLFU(val);
} else {
val->lru = LRU_CL
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值