专栏首页PHPer技术栈Redis过期策略以及内存淘汰机制

Redis过期策略以及内存淘汰机制

如果你的 Redis 只能存10G数据,你写了12G,那么 Redis 会怎么淘汰那2G数据呢?

过期键删除策略

我们都知道,删除键的目的,就是释放内存占用。那么,当一个键过期了,Redis 什么时候会去删除它呢?

定时删除

  1. 设置键的过期时间时,创建一个 Timer ,当过期时间到临时,立刻删除键。
  2. 内存友好型策略,一旦键过期,就会被删除,并释放所占用的内存,Cpu 不友好,当一批数量比较多的键过期时,正好遇上Cpu 紧张的时段,这时候需要的是Cpu处理能力,而不是内存,显然 Cpu 时间用在删除过期键上,会对服务器的响应时间和吞吐量造成影响。另外当前 Redis 时间事件(无序链表O(N))无法高效处理大量时间事件,所以定时删除并不是一种好的定时删除策略。

惰性删除

  1. 不管过期的键,在这种策略下,当键在键空间中被取出时,首先检查取出的键是否过期,若过期删除该键,否则,返回该键。
  2. 很明显,惰性删除依赖过期键的被动访问,对于内存不友好,如果一些键长期没有被访问,会造成内存泄露(垃圾数据占用内存)。我们知道,Redis是依赖内存的,所以惰性删除也不是一个好的策略。

定期删除

  1. 由定时删除算法,定期的去检查一定的数据库,删除一定的过期键。
  2. 通过合理的删除操作执行的时长和频率,达到合理的删除过期键。

redis.conf 中的过期淘汰配置

看下 Redis 源码中的默认配

# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
# is reached. You can select among five behaviors:
#最大内存策略:当到达最大使用内存时,你可以在下面5种行为中选择,Redis如何选择淘汰数据库键

#当内存不足以容纳新写入数据时

# volatile-lru -> remove the key with an expire set using an LRU algorithm
# volatile-lru :在设置了过期时间的键空间中,移除最近最少使用的key。这种情况一般是把 redis 既当缓存,又做持久化存储的时候才用。

# allkeys-lru -> remove any key according to the LRU algorithm
# allkeys-lru :移除最近最少使用的key (推荐)

# volatile-random -> remove a random key with an expire set
# volatile-random :在设置了过期时间的键空间中,随机移除一个键,不推荐

# allkeys-random -> remove a random key, any key
# allkeys-random :直接在键空间中随机移除一个键,弄啥叻

# volatile-ttl -> remove the key with the nearest expire time (minor TTL)
# volatile-ttl :在设置了过期时间的键空间中,有更早过期时间的key优先移除 不推荐

# noeviction -> don't expire at all, just return an error on write operations
# noeviction :不做过键处理,只返回一个写操作错误。不推荐

# Note: with any of the above policies, Redis will return an error on write
# operations, when there are no suitable keys for eviction.
# 上面所有的策略下,在没有合适的淘汰删除的键时,执行写操作时,Redis 会返回一个错误。下面是写入命令:
# At the date of writing these commands are: set setnx setex append
# incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd
# sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby
# zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby
# getset mset msetnx exec sort

# 过期策略默认是:
# The default is:
# maxmemory-policy noeviction

其他模块对过期键的处理

生成RDB文件时

执行 SAVE 或 BGSAVE 时 ,数据库键空间中的过期键不会被保存在RDB文件中

载入RDB文件时

  1. Master 载入RDB时,文件中的未过期的键会被正常载入,过期键则会被忽略。
  2. Slave 载入 RDB 时,文件中的所有键都会被载入,当同步进行时,会和Master 保持一致。

AOF 文件写入时

数据库键空间的过期键的过期但并未被删除释放的状态会被正常记录到 AOF 文件中,当过期键发生释放删除时,DEL 也会被同步到 AOF 文件中去。

重新生成 AOF文件时

执行 BGREWRITEAOF 时 ,数据库键中过期的键不会被记录到 AOF 文件中

复制

  1. Master 删除 过期 Key 之后,会向所有 Slave 服务器发送一个 DEL命令,从服务器收到之后,会删除这些 Key。
  2. Slave 在被动的读取过期键时,不会做出操作,而是继续返回该键,只有当Master 发送 DEL 通知来,才会删除过期键,这是统一、中心化的键删除策略,保证主从服务器的数据一致性。

本文分享自微信公众号 - PHPer技术栈(Bule_sky-W),作者:PHPer技术栈

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-11-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 简述TCP的三次握手过程

    对方主动关闭连接或者网络异常导致连接中断,这时我方的状态会变成CLOSE_WAIT 此时我方要调用close()来使得连接正确关闭

    ITer.996
  • PHP7.+系列新特性和新变更

    组合比较符号用于比较两个表达式。当$a小于、等于或大于$b时它分别返回-1、0或1,比较规则延续常规比较规则。对象不能进行比较

    ITer.996
  • 你可能会忽略的 Git 提交规范

    如果你有一个项目,从始至终都是自己写,那么你想怎么写都可以,没有人可以干预你。可是如果在团队协作中,大家都张扬个性,那么代码将会是一团糟,好好的项目就被糟践了。...

    ITer.996
  • Redis的过期键删除策略和数据逐出策略

    在实际生产环境中使用Redis时,偶然会觉得Redis的内存占用要比自己预想的大。事实上,Redis占用的内存除了保存键值对所需的开销外,还有一些运行时产生的额...

    全菜工程师小辉
  • Redis(七)---淘汰删除策略

    LRU算法,least RecentlyUsed,最近最少使用算法。也就是说默认删除最近最少使用的键。

    Coxhuang
  • 这么多人,AI怎么知道你说的是哪个? | 李飞飞团队CVPR论文+代码

    对于人类保安来说,理解这个指令是自然而然毫无难度的事。但机器就不一样了:它们能从画面中认出人人人人人,但究竟哪一个才是“砸玻璃的人”呢?

    量子位
  • FAQ 1:木兰许可证专业解读及首批采用“木兰”开源项目列表

    詹毅律师评 “木兰”许可证是法律文件,是份格式的标准化合约。因此,这个说明,如果想具有同样的效力,不应以文章的形式。而应以“木兰”许可证的附件的形式,以让已经...

    开源社
  • 《利用Python进行数据分析·第2版》 附录A NumPy高级应用A.1 ndarray对象的内部机理A.2 高级数组操作A.3 广播A.4 ufunc高级应用A.5 结构化和记录式数组A.6 更多

    在这篇附录中,我会深入NumPy库的数组计算。这会包括ndarray更内部的细节,和更高级的数组操作和算法。 这章包括了一些杂乱的章节,不需要仔细研究。 A.1...

    SeanCheney
  • Django打造大型企业官网(四)

    zhang_derek
  • Effective.Java 读书笔记(9)关于HashCode

    有很多程序会错误的原因之一,就是当你重写一个类的equals方法的时候忘记重写它的hashCode了

    Mezereon

扫码关注云+社区

领取腾讯云代金券