Redis过期数据的删除策略详解

 更新时间:2023年08月24日 09:50:47   作者:Upaaui  
Redis 是一个kv型数据库,我们所有的数据都是存放在内存中的,但是内存是有大小限制的,不可能无限制的增量,这篇文章主要介绍了Redis过期数据的删除策略,需要的朋友可以参考下

1 介绍

Redis 是一个kv型数据库,我们所有的数据都是存放在内存中的,但是内存是有大小限制的,不可能无限制的增量。想要把不需要的数据清理掉,一种办法是直接删除,这个咱们前面章节有详细说过;另外一种就是设置过期时间,缓存过期后,由Redis系统自行删除。这边需要注意的是,缓存过期之后,并不是马上删除的,那Redis是怎么删除过期数据的呢?主要通过两个方式

  • 惰性删除
  • 通过定时任务,定期选取部分数据删除

2 Redis缓存过期命令

我们通过以下指令给指定key的缓存设置过期时间,如果都没设置过期时间, key 将一直存在,直到我们使用 Del 的命令明确删除掉。

# 缓存时间过期命令,参考如下
EXPIRE key seconds [ NX | XX | GT | LT] 

Redis 7.0 开始,EXPIRE 添加了 NX、XX和GT、LT 选项,分别代表如下:

  • NX:仅当Key没有过期时设置过期时间
  • XX:仅当Key已过期时设置过期时间
  • GT:仅当新到期时间大于当前到期时间时设置到期时间
  • LT:仅当新到期时间小于当前到期时间时设置到期时间

其中,GT、LT和NX选项是互斥的,下面是官方的测试用例:

redis> SET mykey "Hello"
"OK"
redis> EXPIRE mykey 10
(integer) 1
redis> TTL mykey
(integer) 10
redis> SET mykey "Hello World"
"OK"
redis> TTL mykey
(integer) -1
redis> EXPIRE mykey 10 XX
(integer) 0
redis> TTL mykey
(integer) -1
redis> EXPIRE mykey 10 NX
(integer) 1
redis> TTL mykey
(integer) 10
 

3 两种过期数据的删除方式

我们前面说过,Redis删除过期数据主要通过以下两个方式,我们一个个来看:

  • 惰性删除
  • 通过定时任务,定期选取部分数据删除

3.1 惰性删除

惰性删除比较简单,当客户端请求过来查询我们的key的时候,先对key做一下检查,如果没过期则返回缓存数据,如果过期,则删除缓存,重新从数据库中获取数据。这样,我们就把删除过期数据的主动权交给了访问请求的客户端,如果客户端一直没请求,那这个过期缓存可能就长时间得不到释放。

Redis的源码 src/db.c 中的 expireIfNeeded 方法 就是实现以上惰性删除逻辑的,我们来看看:

int expireIfNeeded(redisDb *db, robj *key, int force_delete_expired) {
    // 对于未过期的key,直接 return 0
    if (!keyIsExpired(db,key)) return 0;	
	 /* If we are running in the context of a slave, instead of
     * evicting the expired key from the database, we return ASAP:
     * the slave key expiration is controlled by the master that will
     * send us synthesized DEL operations for expired keys.
     *
     * Still we try to return the right information to the caller,
     * that is, 0 if we think the key should be still valid, 1 if
     * we think the key is expired at this time. */
    if (server.masterhost != NULL) {
        if (server.current_client == server.master) return 0;
        if (!force_delete_expired) return 1;
    }
  /* If clients are paused, we keep the current dataset constant,
     * but return to the client what we believe is the right state. Typically,
     * at the end of the pause we will properly expire the key OR we will
     * have failed over and the new primary will send us the expire. */
    if (checkClientPauseTimeoutAndReturnIfPaused()) return 1;
    /* Delete the key */
    deleteExpiredKeyAndPropagate(db,key);
    return 1;
}

3.2 定期删除

刚才前面说过了,仅靠客户端访问来对过期缓存执行删除远远不够,因为有的 key 过期了,但客户端一直没请求,那这个过期缓存可能就长时间甚至永远得不到释放。所以除了惰性删除,Redis 还可以通过定时任务的方式来删除过期的数据。定时任务的发起的频率由redis.conf配置文件中的hz来进行配置

# 代表每1s 运行 10次
hz 10

Redis 默认每 1 秒运行 10 次,也就是每 100 ms 执行一次,每次随机抽取一些设置了过期时间的 key(这边注意不是检查所有设置过期时间的key,而是随机抽取部分),检查是否过期,如果发现过期了就直接删除。该定时任务的具体流程如下:

  • 定时serverCron方法去执行清理,执行频率根据redis.conf中的hz配置的值
  • 执行清理的时候,不是去扫描所有的key,而是去扫描所有设置了过期时间的key(redisDb.expires)
  • 如果每次去把所有过期的key都拿过来,那么假如过期的key很多,就会很慢,所以也不是一次性拿取所有的key
  • 根据hash桶的维度去扫描key,扫到20(可配)个key为止。假如第一个桶是15个key ,没有满足20,继续扫描第二个桶,第二个桶20个key,由于是以hash桶的维度扫描的,所以第二个扫到了就会全扫,总共扫描35个key
  • 找到扫描的key里面过期的key,并进行删除
  • 删除完检查过期的 key 超过 25%,继续执行4、5步

image

其他注意点:

  • 为何不扫描所有key进行过期缓存元素删除:Redis本身就是高速缓存,如果每次检查大量的key,无论在CPU和内存的的使用率上都会特别高,Redis集群越大,风险越大。
  • 分片模式下的删除同步:无论定时删除还是惰性删除。master 会生成删除的指令记录到 AOF 和 slave 节点。

到此这篇关于Redis过期数据的删除策略的文章就介绍到这了,更多相关Redis删除策略内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • redis setex使用方法示例代码

    redis setex使用方法示例代码

    SETEX 是 Redis 中的一个命令,用于设置键的值以及过期时间(以秒为单位),这篇文章主要介绍了redis setex使用方法,需要的朋友可以参考下
    2024-07-07
  • redis-copy使用6379端口无法连接到Redis服务器的问题

    redis-copy使用6379端口无法连接到Redis服务器的问题

    这篇文章主要介绍了redis-copy使用6379端口无法连接到Redis服务器的问题的相关资料,需要的朋友可以参考下
    2023-05-05
  • 详解Redis如何优雅地实现接口防刷

    详解Redis如何优雅地实现接口防刷

    这篇文章主要为大家详细介绍了Redis优雅地实现接口防刷的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-03-03
  • 基于redis实现token验证用户是否登陆

    基于redis实现token验证用户是否登陆

    这篇文章主要为大家详细介绍了基于redis实现token验证用户是否登陆,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-08-08
  • 关于Redis最常见的十道面试题总结大全

    关于Redis最常见的十道面试题总结大全

    Redis作为一个高性能的内存数据存储系统,具有快速读写、持久性、数据结构多样性等特点,广泛应用于各种应用场景,这篇文章主要给大家介绍了关于Redis最常见的十道面试题总结的相关资料,需要的朋友可以参考下
    2024-07-07
  • Redis key键的具体使用

    Redis key键的具体使用

    Redis 是一种键值(key-value)型的缓存型数据库,它将数据全部以键值对的形式存储在内存中,本文就来介绍一下key键的具体使用,感兴趣的可以了解一下
    2024-02-02
  • redis3.2配置文件redis.conf详细说明

    redis3.2配置文件redis.conf详细说明

    redis3.2配置详解,Redis启动的时候,可以指定配置文件,详细说明请看本文说明
    2018-03-03
  • Redis:Redisson分布式锁的使用方式(推荐使用)

    Redis:Redisson分布式锁的使用方式(推荐使用)

    这篇文章主要介绍了Redis:Redisson分布式锁的使用方式(推荐使用),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • Redis实现登录注册的示例代码

    Redis实现登录注册的示例代码

    本文主要介绍了Redis实现登录注册的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Redis Server启动过程的详细步骤

    Redis Server启动过程的详细步骤

    本文主要介绍了Redis Server启动过程的详细步骤,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02

最新评论