您的位置:首页 > 数据库 > Redis

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

2019-03-21 22:42 996 查看

一、内存淘汰机制

Redis 内存淘汰指的是用户存储的一些键被可以被 Redis 主动地从实例中删除

    淘汰机制和 Redis 最大占用内存 maxmemory 值以及过期时间 expireTime 紧密相连,典型的例子是:

  1.  客户端发起了需要申请更多内存的命令(如set)。
  2.  Redis 检查内存使用情况,如果已使用的内存大于 maxmemory 则开始根据用户配置的不同淘汰策略来淘汰已存储的数据(key),从而换取一定的内存。
  3. 如果上面都没问题,则这个命令执行成功。

        注:maxmemory 为 0 的时候表示我们对 Redis 的内存使用没有限制,redis 默认设置 maxmemory 为 0。

常用的淘汰算法:

  •     FIFO:First In First Out,先进先出。判断被存储的时间,离目前最远的数据优先被淘汰。
  •     LRU:Least Recently Used,最近最少使用。判断最近被使用的时间,目前最远的数据优先被淘汰。
  •     LFU:Least Frequently Used,最不经常使用。在一段时间内,数据被使用次数最少的,优先被淘汰。

Redis提供的淘汰策略:

详细解释

  •     noeviction:达到内存限额后返回错误,客户尝试可以导致更多内存使用的命令(大部分写命令,但DEL和一些例外)
  •     allkeys-lru:为了给新增加的数据腾出空间,驱逐键先试图移除一部分最近使用较少的(LRC)。
  •     volatile-lru:为了给新增加的数据腾出空间,驱逐键先试图移除一部分最近使用较少的(LRC),但只限于过期设置键。
  •     allkeys-random: 为了给新增加的数据腾出空间,驱逐任意键
  •     volatile-random: 为了给新增加的数据腾出空间,驱逐任意键,但只限于有过期设置的驱逐键。
  •     volatile-ttl: 为了给新增加的数据腾出空间,驱逐键只有秘钥过期设置,并且首先尝试缩短存活时间的驱逐键

二、常见的过期删除策略

详细参考

(1)定时删除:创建定时器,在时间到了时候,立刻对键进行删除

        过期键能尽可能被删除,并释放内存。在过期键比较多的情况下,删除操作可能会占用一部分CPU时间。当内存不紧张而CPU非常紧张的情况下,会对服务器响应时间和吞吐量造成影响

        例如,当大量请求等待服务器处理时,服务器应该优先处理请求而不是删除过期键。

另外,创建定时器需要用到时间事件(由无序链表实现),以至于查找一个事件的时间复杂度为O(N),并不能高效的处理大量时间事件。

(2)惰性删除:每次从键空间获取键时,都检查是否过期,过期则删除,未过期,则返回该键

       只有取出键时才对其进行过期检查,不会删除其他键,不会花费CPU太多时间。若一个键早已过期,但一直未被取到,它便会一直占用内存。若有大量的未被访问的键,而服务器又不会主动释放,就会造成大量的内存浪费。

(3)定期删除:每隔一段时间删除里面的过期键

        每隔一段时间删除过期键,减少了对cpu占用时间的影响
       也有效的减少了过期键过多而造成的内存浪费
       删除操作执行的时长和频率。既不能太频繁也不能太稀疏,需合理设置

redis中常见的过期键设置命令

  •     SETEX命令可以在设置一个字符串的同时为键设置过期时间。
  •     TTL和PTTL命令接受一个带生存时间或者过期时间的键,返回这个键的剩余时间。
  •     EXPIRE<key><ttl> 将key生存时间设置为ttl秒
  •     PEXPIRE 将key生存时间设置为ttl毫秒
  •     EXPIREAT<key><timestamp> 将键key的过期时间设置为timestamp所指定的秒数时间戳
  •     PEXPIREAT<key><timestamp> 将键key的过期时间设置为timestamp所指定的豪秒数时间戳

redis惰性删除策略


redis定期删除策略

过期键的定期删除策略由redis.c/activeExpireCycle函数实现

  •     函数每次运行时,都从一定数量的数据库中取出一定数量的随机键检查,并删除过期键
  •     全局变量current_db会记录当前函数的检查进度,在下一次调用时,接着上次的进度处理。当前函数遍历10号数据库返回了,下次就会从11号开始
  •     随着函数的执行,所有数据库都被检查一遍后,全局变量current_db会置为0,然后重新开始

复制功能下如何处理

复制模式下,过期键的删除由主服务器控制

  •     主服务删除一个过期键后,会显示的向从服务器发送DEL命令,告知删除该键
  •     从服务器只有接收到主服务器发送来的DEL命令,才会删除过期键。否则不会删除,并且像正常键一样处理

这样可以保持数据的一致性

RDB和AOF时如何处理过期键

RDB

  •     以主服务器模式运行,在载入RDB文件时,未过期的键才会被载入,过期键被忽略
  •     以从服务器模式运行,所有键都将载入

AOF写入

  •     若某键已过期,程序会向AOF文件追加一条DEL,来显示删除

AOF重写

  •     已过期的键不会保存到重写的AOF文件中

 

原文:https://blog.csdn.net/github_35124642/article/details/80576577!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: