前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >理解Redis的内存回收机制和过期淘汰策略

理解Redis的内存回收机制和过期淘汰策略

作者头像
八点半的Bruce、D
发布2020-06-23 11:17:01
1K0
发布2020-06-23 11:17:01
举报
文章被收录于专栏:八点半技术站八点半技术站

01

今天写这篇文章的灵感,来自之前一位好友投稿的面试题:redis 的过期策略有哪些?内存淘汰机制有哪些?我将工作中遇到的问题分析,整理成一篇文章提供大家学习,希望对大家有所帮助。

我们从一次广告数据问题说起:一个依赖定时器任务的生成接口数据,有时候会有,有时候没有。

然后我们分析应该是redis过期删除策略导致。

排查过程中,因为手动执行定时器,set数据没有报错,但是set后不生效。这就狠尴尬。

发现,set 没有报错,但是 set 完毕在查的情况下,发现没有数据。开始怀疑 redis 的过期策略(准确来说应该是 redis 的内存回收机制中的数据淘汰策略触发内存上限淘汰数据),导致新加入的的redis的数据都被丢弃了。

最终发现故障是因为配置问题,导致数据错误。(有时候也会因为内存满)

在这里我主要希望大家明白,我们遇到类似问题,如何有效证明正确性,以及什么情况下怀疑内存回收才是合理,所以内存回收机制的一系列问题,你也要知道了解。

02

Q:为什么需要内存回收?

A:第一种:在redis 中,set 指令可以指定 key 的过期时间,当过期时间达到以后,key 就会失效。

第二种:redis 是基于内存操作的,所有的数据都是保存在内存中,一台机器的内存是很宝贵的。

分析:根据以上这俩种,为了保证 redis 提供有效可靠的服务,redis 需要一种机制清理不常用的、无效的、多余的数据,失效后的数据需要及时清理,这就需要内存回收。

03

redis 的内存回收主要分为:过期删除策略 与 内存淘汰策略 俩部分。

过期删除策略:删除到达过期时间的 key 。(过期删除策略原理 - 结合文章,百度自行搜索)

第一种:定时删除

对于每一个设置了过期时间的 key 都会创建一个定时器,一旦达到过期时间都会删除。这种方式立即清除过期数据,对内存比较好,

但是有缺点是:占用了大量 CPU 的资源去处理过期数据,会影响 redis 的吞吐量 和 响应时间。

第二种:惰性删除

当访问一个 key 的时候,才会判断该 key 是否过期,如果过期就删除。该方式能最大限度节省 CPU 的资源。

但是对内存不太好,有一种比较极端的情况:出现大量的过期 key 没有被再次访问,因为不会被清除,导致占用了大量的内存。

第三种:定期删除

每隔一段时间,扫描redis 中过期key 的字典,并清除部分过期的key。这种方式是前俩种一种折中方法。

不同的情况下,调整定时扫描时间间隔,让CPU 与 内存达到最优。

内存淘汰策略:redis 内存淘汰策略是指达到maxmemory极限时,使用某种算法来决定来清理哪些数据,以保证新数据存入。(原理同上)

redis的内存淘汰机制分为:

(1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。

(2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)。

(3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key。

(4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 key。

(5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 key。

(6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除。

04

总结:看完这些,我们得知道一点,如何证明故障不是由于内存回收机制引起的?

根据上述分析,set 没有报错,但是不生效,那么就2种情况:

(1)设置过期时间过短

(2)内存超过最大限制,且设置的是noeviction或者allkeys-random。

因此,在遇到这种情况,首先看set的时候是否加了过期时间,且过期时间是否合理,如果过期时间较短,那么应该检查一下设计是否合理。

如果过期时间没问题,那就需要查看Redis的内存使用率,查看Redis的配置文件或者在Redis中使用info命令查看Redis的状态,maxmemory属性查看最大内存值。

如果是0,则没有限制,此时是通过total_system_memory限制,对比used_memory与Redis最大内存,查看内存使用率。

如果当前的内存使用率较大,那么就需要查看是否有配置最大内存,如果有且内存超了,那么就可以初步判定是内存回收机制导致key设置不成功,还需要查看内存淘汰算法是否noeviction或者allkeys-random.

如果是,则可以确认是redis的内存回收机制导致。

如果内存没有超,或者内存淘汰算法不是上面的两者,则还需要看看key是否已经过期,通过ttl查看key的存活时间。

如果运行了程序,set没有报错,则ttl应该马上更新,否则说明set失败,如果set失败了那么就应该查看操作的程序代码是否正确了。

全文思维导图:

恭喜你,又读完了一篇文章。

在这里,希望你看完的 每篇文章 都能对自己有所提升(哪怕是帮助你再次巩固记忆)。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 八点半技术站 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档