前方高能!Redis如何清除过期key? 这篇文章带你走近源码

当Redis内存过高时,会触发清理策略,包括近似LRU和LFU。Redis会对所有db进行清理,采样key并根据空闲时间排序。源码分析揭示了填充过期池和执行清理的逻辑,以及不同清理策略的实现。
摘要由CSDN通过智能技术生成

​​​​业务组的同学告诉我说很多用户的帐号今天被强制下线。我们的帐号系统正常的逻辑是用户登录一次后,token的有效期可以维持一天的时间。现在的问题是用户大概每10分钟左右就需要重新登录一次。这种情况一般有两种原因:

  • 1、token生成时出问题。
  • 2、验证token时出现问题。

通过检查日志,我发现是验证token时,Redis中已经没有对应的token了。并且确定了生成新的token时,set到Redis中的有效期是正确的,那么就基本可以确定是Redis的问题了。

于是又去检查了Redis的监控,发现在那段时间Redis由于内存占用过高强制清理了几次key。但从日志上来看,这段时间并没有出现流量暴涨的情况,而且Redis中key的数量也没有显著增加。那是什么原因导致Redis内存占用过高呢?确定了Redis内存升高不是我们造成的之后,我们又联系了业务组的同学协助他们,他们表示最近确实有上线,并且新上线的功能有使用到Redis。但我仍然感觉很奇怪,为什么Redis中的key没有增多,并且没看到有其他业务的key。经过一番询问,才了解到,业务组同学使用的是这个Redis的db1,而我用的(和刚查的)是db0。这里确实是我在排查问题时出现了疏忽。

那么Redis的不同db之间会互相影响吗?通常情况下,我们使用不同的db进行数据隔离,这没问题。但Redis进行清理时,并不是只清理数据量占用最大的那个db,而是会对所有的db进行清理。在这之前我并不是很了解这方面知识,这里也只是根据现象进行的猜测。

好奇心驱使我来验证一下这个想法。于是我决定直接来看Redis的源码。清理key相关的代码在evict.c文件中。

Redis中会保存一个“过期key池”,这个池子中存放了一些可能会被清理的key。其中保存的数据结构如下:

struct evictionPoolEntry {
    unsigned long long idle;    /* Object idle time (inverse frequency for LFU) */
    sds key;                    /* Key name. */
    sds cached;                 /* Cached SDS object for key name. */
    int dbid;                   /* Key DB number. */
};

其中idle是对象空闲时间,在Reids中,key的过期算法有两种:一种是近似LRU,一种是LFU。默认使用的是近似LRU。

近似LRU

在解释近似LRU之前,先来简单了解一下LRU。当Redis的内存占用超过我们设置的maxmemory时,会把长时间没有使用的key清理掉。按照LRU算法,我们需要对所有key(也可以设置成只淘汰有过期时间的key)按照空闲时间进行排序,然后淘汰掉空闲时间最大的那部分数据,使得Redis的内存占用降到一个合理的值。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值