Redis(三十三)-Redis键过期时间设置以及过期键删除策略

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: 在Redis中我们可以通过四个不同的命令来给键设置过期时间

键的过期时间如何设置?

在Redis中我们可以通过四个不同的命令来给键设置过期时间,分别是:

1.EXPIRE <key> <ttl> 命令用于将键key的生存时间设置成ttl秒。(TTL的意思是 Time To Live)

2.PEXPIRE <key> <ttl> 命令将键key的生存时间设置成ttl毫秒。

3.PEXPIREAT <key> <timestamp> 命令用于将键key的过期时间设置为timestamp锁所指定的秒数时间戳。

4.PEXPIREAT <key> <timestamp> 命令用于将键key的过期时间设置为timestamp所指定的毫秒数时间戳。

虽然有多种不同单位和不同形式的设置命令,但实际上EXPIRE、PEXPIRE、EXPIREAT三个命令都是使用PEXPIREAT命令来实现的。无论客户端执行的是以上四个命令中的哪一个,经过转换之后,最终的执行结果都和执行PEXPIREAT命令一样。

过期时间如何保存?

redisDb结构的expires字典保存了数据库中所有键的过期时间,我们称这个字典为过期字典,过期字典的键是一个指针,这个指针指向键空间中的某个键对象(也即是某个数据库键),键空间的键和过期字典的键都是指向同一个键对象。另外,过期字典的值是一个long long类型的整数,这个整数保存了键所指向的数据库键的过期时间,该过期时间是一个毫秒精度的UNIX的时间戳。

8d73f141a7e3a008bc1512c68bcf9c70_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTQ1MzQ4MDg=,size_16,color_FFFFFF,t_70#pic_center.png

这里的时间戳 1600341444018 表示到 2020-09-17 19:20:30秒是键message的过期时间。

过期键如何判定呢?

1.检查一个键是否过期的判定步骤主要有两步:

2.检查给定键是否存在于过期时间,如果存在,那么取键的过期时间。

检查当前UNIX时间戳是否大于键的过期时间,如果是的话,那么键已经过期,否则键未过期。

用伪代码描述如下:

def is_expired(key):
      #取得键的过期时间
  expire_time_in_ms=redisDb.expries.get(key)
  #键没有设置过期时间
  if expire_time_in_ms is None: 
    return false
  #取得当前时间的UNIX时间戳
  now_ms=get_current_unix_timestamp_in_ms()
  #检查当前时间是否大于键的过期时间
  if now_ms>expire_time_in_ms:
    #是,键已经过期
    return true
  else:
    #否,键未过期
    return false

实现过期键判定的另一种方法是使用TTL命令或者PTTL命令,比如说,如果对某个键执行TTL命令,并且命令返回的值大于等于0,那么说明该键未过期,在实际中,Redis检查键是否过期的方法和is_expireed函数所描述的方法一致,因为直接访问字典比执行一个命令稍快一些。

如何删除带过期时间的键?

通过前面的介绍,我们知道了数据库键的过期时间都是保存在过期字典中,又知道了如何判断一个键是否过期,现在有个问题是,当键过期是否,是否会立即删除?Redis有三种过期键删除策略。


1.定时删除:在设置键的过期时间的同时,创建一个定时器(timer),让定时器在键的过期时间来临时,立即执行对键的删除操作。这种策略可以保证过期键会被尽快地被删除,并释放过期键所占用的内存。但是它对CPU时间是最不友好的,在过期键比较多的情况下,删除过期键这一行为可能会占用相当一部分CPU时间,无疑会对服务器的响应时间和吞吐量造成影响。


2.惰性删除:放任键过期不管,但是每次从键空间中获取键时,都会检查取得的键是否过期,如果过期的话,就会删除该键,如果没有过期,就返回该键。该策略对CPU时间来说是最友好的,程序只会在取出键时才会对键进行过期检查,这可以保证删除过期键的操作只会在非做不可的情况下进行。但是它的缺点就是对内存是最不友好的,如果一个键已经过期,而这个键又仍然保留在数据库中,那么只要这个过期键不被删除,它所占用的内存就不会被释放。


3.定期删除:每隔一段时间(默认是每隔100ms,在配置文件中由hz参数控制,取值范围是1~500),会扫描一定数量的数据库的expires字典中的一定数量的key。并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。它具体的清理过程是:

遍历所有的db

从过期字典的key的集合中随机检查20个key

删除检查中发现的所有过期key

如果检查结果中25%以上的key已过期,则继续重复执行步骤2和步骤3,否则继续遍历下一个db。

调大hz将会提高redis定期任务的执行频率,如果你的redis中包含很多过期key的话,可以考虑将这个值调大,但要注意同时也会增加CPU的压力,redis作者建议这个值不要超过100。

Redis中同时使用了惰性过期和定期过期两种过期策略。

Redis的内存淘汰策略

当使用内存大于maxmemory时,就会触发Redis主动淘汰内存方式:

volatile-lru:利用LRU算法移除设置过过期时间的key(LRU:最近使用Least Recently Used),例如:有个是3个key,a最近10分钟使用了100次,b最近10分钟使用了50次,c最近一个小时使用了1次,那么会淘汰掉c。

allkeys-lru: 利用LRU算法移除任何key(和上一个相比,删除的key包括设置过期时间的和不设置过期时间的),通常使用该方式。

volatile-random:移除设置过过期时间的随机key;

allkeys-random:无差别的随机移除

volatile-ttl:移除即将过期的key(minor TTL)

noeviction:不移除任何key,只是返回一个写错误,默认选项,一般不会选用。

可以通过设置 maxmemory-policy 来设置内存淘汰方式:

aof/rdb和复制功能对过期键的处理

rdb

生成rdb文件: 生成时,程序会对键进行检查,过期键不会放入rdb文件。

载入rdb文件:载入时,如果以主服务器模式运行,程序会对文件中保存的键进行检查,未过期的键会被载入到数据库中,而过期键则会忽略;如果以从服务器模式运行,无论键过期与否,均会载入数据库中,过期键会通过与主服务器同步而删除。

aof

当服务器以aof持久化模式运行时,如果数据库中某个键已经过期,但它还没有被删除,那么aof文件不会因为这个过期键而产生任何影响;当过期键被删除后,程序会向aof文件追加一条del命令来显式记录该键已被删除。

aof重写过程中,程序会对数据库中的键进行检查,已过期的键不会被保存到重写后的aof文件中。

复制

当服务器运行在复制模式下时,从服务器的过期删除动作由主服务器控制:

主服务器在删除一个过期键后,会显式地向从服务器发送一个del命令,告知从服务器删除这个过期键;

从服务器在执行客户端发送的读命令时,即使碰到过期键也不会将过期键删除,而是继续像处理未过期的键一样来处理过期键;

从服务器只有在接到主服务器发来的del命令后,才会删除过期键。

总结

本文主要从Redis键过期时间的设置,过期时间的保存以及过期键的删除策略四个方面对Redis中键过期时间进行了阐述。


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1月前
|
NoSQL Redis
05- Redis的数据淘汰策略有哪些 ?
Redis 提供了 8 种数据淘汰策略:挥发性 LRU、LFU 和 TTL(针对有过期时间的数据),挥发性随机淘汰,以及全库的 LRU、LFU 随机淘汰,用于在内存不足时选择删除。另外,还有不淘汰策略(no-eviction),允许新写入操作报错而非删除数据。
318 1
|
1月前
|
存储 NoSQL Redis
04- Redis的数据过期策略有哪些 ?
Redis的数据过期策略包括**惰性删除**和**定期删除**。惰性删除在取出key时检查是否过期,节省CPU但可能延迟清理。定期删除则每隔一定时间删除一批过期key,通过限制操作频率减少CPU影响。默认每秒扫描10次,随机抽取20个键,若25%已过期则继续检查,最大执行时间25ms。Redis使用这两种策略的结合以平衡内存和CPU使用。
20 1
|
1月前
|
NoSQL Redis
03- Redis的数据持久化策略有哪些 ?
Redis的数据持久化包括两种策略:RDB(全量快照)和AOF(增量日志)。RDB在指定时间间隔将内存数据集保存到磁盘,而AOF记录所有写操作形成日志。从Redis 4.0开始,支持RDB和AOF的混合持久化,通过设置`aof-use-rdb-preamble yes`。
29 1
|
1月前
|
缓存 NoSQL 数据库
探秘Redis读写策略:CacheAside、读写穿透、异步写入
本文介绍了 Redis 的三种高可用性读写模式:CacheAside、Read/Write Through 和 Write Behind Caching。CacheAside 简单易用,但可能引发数据不一致;Read/Write Through 保证数据一致性,但性能可能受限于数据库;Write Behind Caching 提高写入性能,但有数据丢失风险。开发者应根据业务需求选择合适模式。
256 2
探秘Redis读写策略:CacheAside、读写穿透、异步写入
|
1月前
|
存储 监控 NoSQL
Redis处理大量数据主要依赖于其内存存储结构、高效的数据结构和算法,以及一系列的优化策略
【5月更文挑战第15天】Redis处理大量数据依赖内存存储、高效数据结构和优化策略。选择合适的数据结构、利用批量操作减少网络开销、控制批量大小、使用Redis Cluster进行分布式存储、优化内存使用及监控调优是关键。通过这些方法,Redis能有效处理大量数据并保持高性能。
48 1
|
1月前
|
NoSQL Redis 数据安全/隐私保护
redis设置密码
redis设置密码
104 1
|
1天前
|
存储 Prometheus 监控
Redis 调优指南:提高性能和稳定性的全面策略
Redis 调优指南:提高性能和稳定性的全面策略
6 0
|
6天前
|
存储 监控 NoSQL
Redis中的LRU淘汰策略深入解析
Redis的内存管理关键在于处理数据增长与有限内存的矛盾,LRU策略被广泛用于此。LRU基于“不常访问的数据未来访问可能性小”的假设,淘汰最近最少使用的数据。Redis通过双向链表实现,但并非严格LRU,而是采样算法以平衡性能和精度。用户可通过调整`maxmemory-samples`等参数优化。尽管LRU简单高效,但无法区分数据重要性和访问频率,可能误淘汰重要数据。合理设置参数、结合其他策略、监控调优是优化LRU使用的关键。
10 1
|
10天前
|
缓存 NoSQL 关系型数据库
Redis第二课,1.set key value(设置对应的key和value)2.get key(得到value值)Redis全局命令(支持很多的数据结构)3.keys(用来查询当前
Redis第二课,1.set key value(设置对应的key和value)2.get key(得到value值)Redis全局命令(支持很多的数据结构)3.keys(用来查询当前
|
16天前
|
存储 缓存 NoSQL
Redis 缓存失效策略及其应用场景
Redis 缓存失效策略及其应用场景
39 1