浅谈redis的过期时间设置和过期删除机制

目录
  • 一:设置过期时间
  • 二:保存过期时间
  • 三:移除过期时间
  • 四:计算并返回剩余生存时间
  • 五:过期键的删除策略
  • 六:redis使用的策略

一:设置过期时间

redis有四种命令可以用于设置键的生存时间和过期时间:

  • EXPIRE <KEY> <TTL> : 将键的生存时间设为 ttl 秒
  • PEXPIRE <KEY> <TTL> :将键的生存时间设为 ttl 毫秒
  • EXPIREAT <KEY> <timestamp> :将键的过期时间设为 timestamp 所指定的秒数时间戳
  • PEXPIREAT <KEY> <timestamp>: 将键的过期时间设为 timestamp 所指定的毫秒数时间戳.

二:保存过期时间

那么redis里面对这些key的过期时间和生存时间的信息是怎么保存的呢??
答:在数据库结构redisDb中的expires字典中保存了数据库中所有键的过期时间,我们称expire这个字典为过期字典。
(1)过期字典是一个指针,指向键空间的某个键对象。
(2)过期字典的值是一个longlong类型的整数,这个整数保存了键所指向的数据库键的过期时间–一个毫秒级的 UNIX 时间戳。

下图是一个带过期字典的数据库例子:

过期字典是存储在redisDb这个结构里的:

typedef struct redisDb {
    ...

    dict *dict;     //数据库键空间,保存着数据库中所有键值对
    dict *expires      // 过期字典,保存着键的过期时间
    ...
} redisDb;

从以上结构中可以看到expire字典(过期字典)和dict字典(数据库键空间,保存着数据库中所有键值对)是并列的,由此可见expire字典的重要性。

三:移除过期时间

PERSIST 命令可以移除一个键的过期时间:

127.0.0.1:6379> set message "hello"
OK
127.0.0.1:6379> expire message 60
(integer) 1
127.0.0.1:6379> ttl message
(integer) 54
127.0.0.1:6379> persist message
(integer) 1
127.0.0.1:6379> ttl message
(integer) -1

persist命令就是expire命令的反命令,这个函数在过期字典中查找给定的键,并从过期字典中移除。
比如在数据库当前状态(如上图所示),当给book这个key移除过期时间:

redis> persist book
(integer) 1

数据库将更新成如下状态:

可以从图中看到,当PERSIST book命令执行之后,过期字典中的 book 键消失了。

四:计算并返回剩余生存时间

ttl命令以秒为单位返回指定键的剩余生存时间。pttl以毫秒返回。两个命令都是通过计算当前时间和过期时间的差值得到剩余生存期的。

127.0.0.1:6379> set minping shuxin
OK
127.0.0.1:6379> expire minping 60
(integer) 1
127.0.0.1:6379> ttl minping
(integer) 57
127.0.0.1:6379> ttl minping
(integer) 27
127.0.0.1:6379> pttl minping
(integer) 23839
127.0.0.1:6379>

redis源码为:

void ttlCommand(redisClient *c) {
    ttlGenericCommand(c, 0);
}
void pttlCommand(redisClient *c) {
    ttlGenericCommand(c, 1);
}
void ttlGenericCommand(redisClient *c, int output_ms) {
    long long expire, ttl = -1;
    /* 如果键不存在,返回-2 */
    if (lookupKeyRead(c->db,c->argv[1]) == NULL) {
        addReplyLongLong(c,-2);
        return;
    }

    /* 如果键存在*/
    /*如果没有设置生存时间,返回 -1, 否则返回实际剩余时间 */
    expire = getExpire(c->db,c->argv[1]);
    if (expire != -1) {
        /* 过期时间减去当前时间,就是键的剩余时间*/
        ttl = expire-mstime();
        if (ttl < 0) ttl = 0;
    }
    if (ttl == -1) {
        addReplyLongLong(c,-1);
    } else {
         /*将毫秒转化为秒*/
        addReplyLongLong(c,output_ms ? ttl : ((ttl+500)/1000));
    }
}

五:过期键的删除策略

如果一个键是过期的,那它到了过期时间之后是不是马上就从内存中被被删除呢??如果不是,那过期后到底什么时候被删除呢??

其实有三种不同的删除策略:
(1):立即删除。在设置键的过期时间时,创建一个回调事件,当过期时间达到时,由时间处理器自动执行键的删除操作。
(2):惰性删除。键过期了就过期了,不管。每次从dict字典中按key取值时,先检查此key是否已经过期,如果过期了就删除它,并返回nil,如果没过期,就返回键值。
(3):定时删除。每隔一段时间,对expires字典进行检查,删除里面的过期键。
可以看到,第二种为被动删除,第一种和第三种为主动删除,且第一种实时性更高。下面对这三种删除策略进行具体分析。

立即删除

立即删除能保证内存中数据的最大新鲜度,因为它保证过期键值会在过期后马上被删除,其所占用的内存也会随之释放。但是立即删除对cpu是最不友好的。因为删除操作会占用cpu的时间,如果刚好碰上了cpu很忙的时候,比如正在做交集或排序等计算的时候,就会给cpu造成额外的压力。

而且目前redis事件处理器对时间事件的处理方式--无序链表,查找一个key的时间复杂度为O(n),所以并不适合用来处理大量的时间事件。

惰性删除

惰性删除是指,某个键值过期后,此键值不会马上被删除,而是等到下次被使用的时候,才会被检查到过期,此时才能得到删除。所以惰性删除的缺点很明显:浪费内存。dict字典和expires字典都要保存这个键值的信息。

举个例子,对于一些按时间点来更新的数据,比如log日志,过期后在很长的一段时间内可能都得不到访问,这样在这段时间内就要拜拜浪费这么多内存来存log。这对于性能非常依赖于内存大小的redis来说,是比较致命的

定时删除

从上面分析来看,立即删除会短时间内占用大量cpu,惰性删除会在一段时间内浪费内存,所以定时删除是一个折中的办法。
定时删除是:每隔一段时间执行一次删除操作,并通过限制删除操作执行的时长和频率,来减少删除操作对cpu的影响。另一方面定时删除也有效的减少了因惰性删除带来的内存浪费。

六:redis使用的策略

redis使用的过期键值删除策略是:惰性删除加上定期删除,两者配合使用。

到此这篇关于浅谈redis的过期时间设置和过期删除机制的文章就介绍到这了,更多相关redis的过期时间设置和过期删除内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Redis 如何批量设置过期时间(PIPLINE的使用)

    合理的使用缓存策略对开发同学来讲,就好像孙悟空习得自在极意功一般~ Redis如何批量设置过期时间呢? 不要说在foreach中通过set()函数批量设置过期时间 我们引入redis的PIPLINE,来解决批量设置过期时间的问题. PIPLINE的原理是什么? 未使用pipline执行N条命令 使用pipline执行N条命令 通过图例可以很明显的看出来PIPLINE的原理: 客户端通过PIPLINE拼接子命令,只需要发送一次请求,在redis收到PIPLINE命令后,处理PIPLINE组成的命令

  • Redis 事务与过期时间详细介绍

    Redis 事务与过期时间详细介绍 一.Redis事务: Redis中支持事务,事务即为当我们需要执行几条命令时,要么这几条命令都不执行,要么都执行: 1.开始事务写入: multi 2.然后写入命令,注意写完事务要执行的每条命令之后回车即可,命令会自动入队: lpush art:1 hello lpush art:1 nihao 3.执行事务: exec Redis则会保证事务中的所有命令要么都执行,要么都不执行. 二.Redis过期时间: 实际开发中经常会遇到一些有时效性的数据,比如缓存,过

  • 浅谈redis的过期时间设置和过期删除机制

    目录 一:设置过期时间 二:保存过期时间 三:移除过期时间 四:计算并返回剩余生存时间 五:过期键的删除策略 六:redis使用的策略 一:设置过期时间 redis有四种命令可以用于设置键的生存时间和过期时间: EXPIRE <KEY> <TTL> : 将键的生存时间设为 ttl 秒 PEXPIRE <KEY> <TTL> :将键的生存时间设为 ttl 毫秒 EXPIREAT <KEY> <timestamp> :将键的过期时间设为

  • php中session过期时间设置及session回收机制介绍

    网上很多人给出了解答:修改配置文件中的session.gc_maxlifetime.如果想了解更多session回收机制,继续阅读.(本文环境php5.2) 概述:每一次php请求,会有1/100的概率(默认值)触发"session回收".如果"session回收"发生,那就会检查/tmp/sess_*的文件,如果最后的修改时间到现在超过了1440秒(gc_maxlifetime的值),就将其删除,意味着这些session过期失效. 1. session在端(一般是

  • 浅谈redis的maxmemory设置以及淘汰策略

    redis的maxmemory参数用于控制redis可使用的最大内存容量.如果超过maxmemory的值,就会动用淘汰策略来处理expaire字典中的键. 关于redis的淘汰策略: Redis提供了下面几种淘汰策略供用户选择,其中默认的策略为noeviction策略: ·   noeviction:当内存使用达到阈值的时候,所有引起申请内存的命令会报错. ·   allkeys-lru:在主键空间中,优先移除最近未使用的key. ·   volatile-lru:在设置了过期时间的键空间中,优

  • 浅谈Redis的几个过期策略

    概述 设置过期时间 expire key time(以秒为单位) 这是最常用的方式 setex(String key, int seconds, String value) 字符串独有的方式 除了字符串自己独有设置过期时间的方法外,其他方法都需要依靠expire方法来设置时间如果没有设置时间,那缓存就是永不过期如果设置了过期时间,之后又想让缓存永不过期,使用persist key 三种过期策略 定时删除 在设置key的过期时间的同时,为该key创建一个定时器,让定时器在key的过期时间来临时,对

  • 浅谈Redis中的内存淘汰策略和过期键删除策略

    目录 8种淘汰策略 过期键的删除策略 总结 redis是我们现在最常用的一个工具,帮助我们建设系统的高可用,高性能. 而且我们都知道redis是一个完全基于内存的工具,这也是redis速度快的一个原因,当我们往redis中不断缓存数据的时候,其内存总有满的时候(而且内存是很贵的东西,尽量省着点用),所以尽可能把有用的数据,或者使用频繁的数据缓存在redis中,物尽其用. 那么如果正在使用的redis内存用完了,我们应该怎么取舍redis中已存在的数据和即将要存入的数据呢,我们要怎么处理呢? re

  • 浅谈Redis对于过期键的三种清除策略

    目录 Pre Redis Key的超时设置处理 被动删除 主动删除 当前已用内存超过maxmemory限定时,触发主动清理策略 对于过期键一般有三种删除策略 定时删除:在设置键的过期时间的同时,创建一个定时器(timer),让定时器在键的过期时间来临时,立即执行对键的删除操作: 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键:如果没有过期,那就返回该键: 定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键.至于删除多少过期

  • 浅谈Redis 中的过期删除策略和内存淘汰机制

    目录 前言 Redis 中 key 的过期删除策略 1.定时删除 2.惰性删除 3.定期删除 Redis 中过期删除策略 从库是否会脏读主库创建的过期键 内存淘汰机制 内存淘汰触发的最大内存 有哪些内存淘汰策略 内存淘汰算法 LRU LFU 为什么数据删除后内存占用还是很高 内存碎片如何产生 碎片率的意义 如何清理内存碎片 总结 参考 前言 Redis 中的 key 设置一个过期时间,在过期时间到的时候,Redis 是如何清除这个 key 的呢? 这来分析下 Redis 中的过期删除策略和内存淘

  • 浅谈Redis 中的过期删除策略和内存淘汰机制

    目录 前言 Redis 中 key 的过期删除策略 1.定时删除 2.惰性删除 3.定期删除 Redis 中过期删除策略 从库是否会脏读主库创建的过期键 内存淘汰机制 内存淘汰触发的最大内存 有哪些内存淘汰策略 内存淘汰算法 LRU LFU 为什么数据删除后内存占用还是很高 内存碎片如何产生 碎片率的意义 如何清理内存碎片 总结 参考 前言 Redis 中的 key 设置一个过期时间,在过期时间到的时候,Redis 是如何清除这个 key 的呢? 这来分析下 Redis 中的过期删除策略和内存淘

  • 手写redis@Cacheable注解 支持过期时间设置方式

    目录 原理解释 实现方法 源代码 原理解释 友情链接  手写redis @ Cacheable注解参数java对象作为键值 @Cacheable注解作用,将带有该注解方法的返回值存放到redis的的中; 使用方法在方法上使用@Cacheable(键=“测试+#P0 + P1#...”) 表示键值为测试+方法第一个参数+方法第二个参数,值为该方法的返回值. 以下源代码表示获取人员列表,Redis的中存放的关键值为'领袖'+ leaderGroupId + UUID + yearDetailId @

  • 浅谈Redis中的自动过期机制

    目录 Redis中的自动过期机制 一.使用Redis Key自动过期机制 二.SpringBoot整合key失效监听 Redis中的自动过期机制 实现需求:处理订单过期自动取消,比如下单30分钟未支付自动更改订单状态 1.使用Redis Key自动过期出发事件通知2.使用定时任务30分钟后检查3.按照每分钟轮训检查 CREATE TABLE `order_number` ( `id` int(11) NOT NULL AUTO_INCREMENT, `order_name` varchar(25

随机推荐