文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

面试必问:Redis过期Key删除和内存淘汰策略

2024-12-13 23:57

关注

本文转载自微信公众号「虫爸说说」,作者虫爸 。转载本文请联系虫爸说说公众号。

众所周知,Redis是一种内存级kv数据库,所有的操作都是在内存里面进行,定期通过异步操作把数据库数据flush到硬盘上进行保存。因此它是纯内存操作,Redis的性能非常出色,每秒可以处理超过10万次读写操作。虽然是内存数据库,但是其数据可以持久化,而且支持丰富的数据类型。

正因为是内存级操作,那么其受限于物理内存,所以Redis提供了过期key的删除以及内存淘汰策略,从而在一定程度上,能够避免达到内存上限。

在本文中,我们首先介绍下如何对某个key设置过期时间,然后再次介绍对于这些过期key都有哪些处理策略,随后分析下在内存达到上限时候,redis采取的策略。

设置过期

redis中设置过期时间有四种方式:

下面,我们来看看具体命令的用法。

expire: N秒后过期

  1. 127.0.0.1:6379> set key value 
  2. OK 
  3. 127.0.0.1:6379> expire key 100 
  4. (integer) 1 
  5. 127.0.0.1:6379> ttl key 
  6. (integer) 93 

其中命令TTL的全称是 time to live,意思是key在N秒后过期。比如上面的结果93表示key在93s后过期。

pexpire: N毫秒后过期

  1. 127.0.0.1:6379> set key2 value2 
  2. OK 
  3. 127.0.0.1:6379> pexpire key2 100000 
  4. (integer) 1 
  5. 127.0.0.1:6379> pttl key2 
  6. (integer) 94524 

pexpire key2 100000 表示 key2 设置为在 100000 毫秒(100 秒)后过期。

expireat: 在某个时间戳过期(精确到秒)

  1. 127.0.0.1:6379> set key3 value3 
  2. OK 
  3. 127.0.0.1:6379> expireat key3 1630644399 
  4. (integer) 1 
  5. 127.0.0.1:6379> ttl key3 
  6. (integer) 67 

expired Key3 1630644399(精确到秒)之后过期。使用TTL查询,可以发现Key3会在67s后过期。

在redis中,可以使用time命令查询当前时间的时间戳(精确到秒),例如:

127.0.0.1:6379> time

1) "1630644526"

2) "239640"

pexpireat: 在某个时间戳过期(精确到毫秒)

  1. 127.0.0.1:6379> set key4 value4 
  2. OK 
  3. 127.0.0.1:6379> pexpireat key4 1630644499740 
  4. (integer) 1 
  5. 127.0.0.1:6379> pttl key4 
  6. (integer) 3522 

其中,pexpireat key4 1630644499740表示key4在时间戳1630644499740(精确到毫秒)之后过期。使用TTL查询可以发现key4会在3522ms后过期。

value为string时候的过期设置

直接操作value为string的过期时间有几种方法,如下所示:

设置kv对在N秒后过期

  1. 127.0.0.1:6379> set k v ex 100 
  2. OK 
  3. 127.0.0.1:6379> ttl k 
  4. (integer) 97 

设置kv对在N毫秒后过期

  1. 127.0.0.1:6379> set k2 v2 px 100000 
  2. OK 
  3. 127.0.0.1:6379> pttl k2 
  4. (integer) 92483 

使用setex来设置

  1. 127.0.0.1:6379> setex k3 100 v3 
  2. OK 
  3. 127.0.0.1:6379> ttl k3 
  4. (integer) 91 

取消过期

使用命令:persist key去除key值的过期时间,如下代码所示:

  1. 127.0.0.1:6379> ttl k3 
  2. (integer) 97 
  3. 127.0.0.1:6379> persist k3 
  4. (integer) 1 
  5. 127.0.0.1:6379> ttl k3 
  6. (integer) -1 

可以看出,第一次使用TTL查询K3,97s后就会过期。使用persist命令查询K3的生命周期的结果是-1,表示K3永不过期。

过期策略

redis对过期key的删除策略,有定时删除、定期删除和惰性删除三种。

定时删除

创建一个定时器,当key设置有过期时间,且过期时间到达时,由定时器任务执行对key的删除操作。

定期删除

redis默认是每隔100ms就随机抽取一些设置了过期时间的key,检查其是否过期,如果过期就删除。注意这里是随机抽取的。为什么要随机呢?假如redis存了几十万个key,每隔100ms就遍历所有的设置过期时间的key的话,就会给CPU带来很大的负载。

如果执行的太频繁,定期删除策略变得和定时删除策略一样,对CPU不友好,如果执行的太少,那又和惰性删除一样了,过期键占用的内存不会及时得到释放。

另外最重要的是,在获取某个键时,如果某个键的过期时间已经到了,但是还没执行定期删除,那么就会返回这个键的值,这是业务不能忍受的错误。

惰性删除

定期删除可能会导致很多过期key到了时间并没有被删除掉。所以就有了惰性删除。假如你的过期key,靠定期删除没有被删除掉,还停留在内存里,除非你的系统去查一下那个key,才会被redis给删除掉。这就是所谓的惰性删除。expireIfNeeded(),检查数据是否过期,执行get的时候调用。

换句话说,惰性删除就是用存储空间换取处理器性能

结合上述三种策略的优缺点,redis采取了折中的删除策略,即采用的是定期删除+惰性删除策略。

定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下,CPU要将时间应用在处理请求,而不是删除key,因此没有采用这一策略

定期删除+惰性删除是如何工作的呢?

定期删除,redis默认每个100ms检查,是否有过期的key,有过期key则删除。需要说明的是,redis不是每个100ms将所有的key检查一次,而是随机抽取进行检查(如果每隔100ms,全部key进行检查,redis岂不是卡死)。因此,如果只采用定期删除策略,会导致很多key到时间没有删除。

惰性删除,也就是说在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除。

但是这种方案,仍然存在缺点: 如果定期删除没删除key。然后你也没及时去请求key,也就是说惰性删除也没生效。这样,redis的内存会越来越高。那么就应该采用内存淘汰机制。

内存淘汰策略

maxmemory 用于指定 Redis 能使用的最大内存。既可以在 redis.conf 文件中设置, 也可以在运行过程中通过 CONFIG SET 命令动态修改。

例如, 要设置 100MB 的内存限制, 可以在 redis.conf 文件中这样配置:

  1. maxmemory 100mb 

上述命令设置了redis内存上限,当内存中的数据量达到其设置的上限的时候,就需要采取一定的淘汰策略,否则会影响redis的正常访问。

为了更好的实现这一点,必须针对不同的应用场景提供不同的策略,下面,我们将介绍下redis支持的几种内存淘汰策略。

Redis 提供了以下几种策略供用户选择,其中noeviction 策略的默认策略为。

需要注意的是,如果没有设置 expire 的key, 不满足先决条件,那么 volatile-lru, volatile-random 和 volatile-ttl 策略的行为, 和 noeviction(不删除) 基本上一致。

Redis 使用的并不是完全LRU算法。自动驱逐的 key , 并不一定是最满足LRU特征的那个. 而是通过近似LRU算法, 抽取少量的 key 样本, 然后删除其中访问时间最古老的那个key。

驱逐算法, 从 Redis 3.0 开始得到了巨大的优化, 使用 pool(池子) 来作为候选. 这大大提升了算法效率, 也更接近于真实的LRU算法。

在 Redis 的 LRU 算法中, 可以通过设置样本(sample)的数量来调优算法精度。

maxmemory-samples 5

以上就是Redis的六种淘汰策略。关于这六种策略的使用,使用者需要根据自身实际需要,选择合理的淘汰策略。读者可以根据自身需求,再结合下面的笔者经验,进行策略选择。

经验之谈

对于redis的操作,我们应该慎之又慎。

 

来源:虫爸说说内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯