Redis的过期策略以及内存淘汰策略原理

Redis是基于内存进行高性能的读写操作。既然是基于内存的那么就一定会达到内存存储的上线。那redis是怎么清除数据以及保留数据呢?这都是由redis的过期策略以及内存的淘汰机制决定的

过期策略

Redis由三种不同的删除策略:定时删除、定期删除、惰性删除。前两种是主动删除策略,最后一种是惰性删除策略。redis本身默认的删除策略是:定期+惰性删除

定时删除:

在设置键的过期时间的同时,创建一个定时器,定时器在过期时间来临时,立即执行删除操作

优点:对内存是最友好的,通过定时器能够保证过期的键能够及时释放

缺点:对cpu不够友好,在过期键比较多的情况下,删除过期键可能会占用非常多的cpu时间,在内存不紧张,CPU比较紧张的情况下,影响服务器的吞吐量以及响应时间。

惰性删除

键过期不管,但是在每次从键空间获取数据时,检查键是否过期,若果过期删除键值

优点:cpu友好,惰性删除保证了删除操作只会发生在非做不可的操作上,保证cpu性能不能浪费在无效的操作上

缺点:内存不友好,如果一个键已经过期,然而这个键一直不会使用到,因此该键所占用的内存得不到释放

定期删除

每隔一段时间,程序对数据进行检查,删除里面的过期键。redis在设置过期时间的时候,会将key放入到单独的字典中,默认会100ms/per扫描一次,过期扫描不会扫描字典中的所有key,采用了贪心的策略。

1.从过期字典中随机20个key

2.删除这20个钟过期的key

3.如果key超过了1/4,重复步骤1

为什么是随机抽取呢?小伙伴可以再评论区留言说一下见解

redis中的配置 redis.conf

# The range is between 1 and 500, however a value over 100 is usually not
# a good idea. Most users should use the default of 10 and raise this up to
# 100 only in environments where very low latency is required.
hz 10 # 默认是1s/10次 可以更改这个值来设置 定期删除频率


内存淘汰策略

有了以上的过期策略说明后,为什么还需要淘汰策略呢?因为定期+惰性并不能保证所有的过期键能够精准的删除,还会存在key没有被删除掉的场景,所以需要内存的淘汰策略

# 内存淘汰策略
# volatile-lru -> remove the key with an expire set using an LRU algorithm
# allkeys-lru -> remove any key according to the LRU algorithm
# volatile-random -> remove a random key 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 expire at all, just return an error on write operations
  • noeviction:返回错误当内存限制达到并且客户端尝试执行会让更多内存被使用的命令(大部分的写入指令,但DEL和几个例外)
  • allkeys-lru: 尝试回收最少使用的键(LRU),使得新添加的数据有空间存放。
  • volatile-lru: 尝试回收最少使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间存放。
  • allkeys-random: 回收随机的键使得新添加的数据有空间存放。
  • volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。
  • volatile-ttl: 回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。

LRU

redis中缓存了一个24位时钟,我们要进行LRU那么我们会首先拿到当前的全局时钟,然后找到内部时钟与全局时钟距离最久的key进行淘汰(24)

redis的LRU算法并非完整的实现,通过对少量的keys进行采样,然后回收其中最好的key(redis为什么不使用真实的LRU,因为需要比较多的内存)。

redis 3.0算法改进为回收键的候选池。redis可以通过调整每次回收检查的采样数量,实现算法的调整 # maxmemory-samples 5。在redis 3中,设置样本数为10的时候能够很准确的淘汰掉最久没有使用的键,真实的LRU算法与近似的算法可以通过下面的图像对比:

近似LRU的好处:

1.性能:真实LRU需要对所有key排序,近似LRU只是随机采样N个,这样性能会有较大提高

2.内存占用:抽样可以减少内存的占用

LFU

Redis 4.0出现,使用频率来进行判断

LFU把原来的key对象的内部时钟的24位分成两部分,前16位还代表时钟,后8位代表一个计数器。16位的情况下如果还按照秒为单位就会导致不够用,所以一般这里以时钟为单位。而后8位表示当前key对象的访问频率,8位只能代表255,但是redis并没有采用线性上升的方式,而是通过一个复杂的公式,通过配置如下两个参数来调整数据的递增速度

 

欢迎关注作者公众号

来源:

http://www.redis.cn/topics/lru-cache.html

https://zhuanlan.zhihu.com/p/105587132

Redis过期策略 实现原理

Redis中的LRU算法实现

书籍:redis设计与实现

原理

 

 

 

 

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术王老五

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值