先说结论:不会马上删。Redis有两种删除过期数据的策略:定期选择一些数据进行删除。懒惰删除。这个命令在Redis2.4版本中,过期时间不是很精确,可能在0到1秒之间。从Redis2.6开始,过期错误在0到1毫秒之间。EXPIRE键秒[NX|XX|GT|LT]指令可以为指定的key设置过期时间。如果没有设置过期时间,那么这个key会一直存在,除非我们明确的删除它,比如执行DEL指令。所谓“狡兔死,走狗煮”,没用就杀了,35岁“毕业”也是这个道理。慌了。。。从Redis7.0.0版本开始:EXPIRE新增选项:NX、XX和GT、LT选项。NX:仅在密钥未过期时才设置过期时间。XX:仅在密钥过期时设置过期时间。GT:仅当新的过期时间大于当前过期时间时才设置过期时间。LT:仅当新的过期时间小于当前过期时间时才设置为过期时间。过期持久化主从或集群架构,两台机器时钟严重不同步,请问是什么问题?密钥过期信息由Unix绝对时间戳表示。为了使过期操作正常进行,机器之间的时间必须稳定且同步,否则过期时间会不准确。例如,当两台时钟严重不同步的机器上发生RDB传输时,slave的时间设置为2000秒以后。如果master中的一个key设置为存活1000秒,当slave加载RDB时,key会认为key过期了(因为slave的机器时间被设置为2000s之后),并不会等待1000s直到到期为止。机器时钟不同步导致过期混乱延迟删除延迟删除很简单,就是当客户端请求查询key时,检查key是否过期,如果过期则删除key。例如,当Redis收到客户端的GETmovie:小泽#马……宗丽.rmvb请求时,会先检查key=movie:小泽#马……Leah.rmvb是否过期,以及如果它过期,请将其删除。删除过期数据的主动权被赋予每个访问请求。这个实现是通过expireIfNeeded函数实现的,源码路径:src/db.c。intexpireIfNeeded(redisDb*db,robj*key,intforce_delete_expired){//key没有过期,返回0if(!keyIsExpired(db,key))return0;if(server.masterhost!=NULL){if(server.current_client==server.master)返回0;如果(!force_delete_expired)返回1;}如果(checkClientPauseTimeoutAndReturnIfPaused())返回1;/*删除密钥*/deleteExpiredKeyAndPropagate(db,key);客户端访问判断key是否过期肯定是不够的,因为有些key已经过期了,但是以后就没有人再访问了,如何删除这些数据呢?我们不能让这些数据“占坑不拉屎”。所谓周期性删除,就是Redis默认每秒运行10次(每100ms)。每次随机选择一些有过期时间的key,检查是否过期。如果发现它们已过期,它们将被直接删除。注意:它不是在一次运行中检查所有库、所有密钥,而是随机检查一定数量的密钥。具体步骤如下:定时删除,从所有设置过期时间的密钥集中随机选取20个密钥。删除“步骤1”中找到的所有过期密钥数据。“Step2”结束,如果过期key超过25%,继续“Step1”。删除源代码expire.c中activeExpireCycle函数的实现。这意味着在任何时候,过期键的最大数量等于每秒最大写入操作数除以4。为什么不检查所有具有过期时间的键呢?想一想,假设Redis中存储了100w个key,都设置了过期时间,每100毫秒检查100w个key,CPU全部浪费在检查过期key上了,Redis就废掉了。注意:无论是定时删除还是惰性删除。当数据被删除时,master会产生删除指令,记录到AOF和slave节点。码哥,如果过期数据太多,定时删除是无法完全删除的(每次删除超过25%的过期key),而且这些key永远不会再被client请求,也就是不能被删除惰性删除了,会怎样?会不会导致Redis内存不足?怎么破?这是一个很好的问题,答案是使用内存淘汰机制。今天就到此为止。说多了,很容易在浩如烟海的知识中窒息而死。挽救您的生命很重要。至于内存淘汰机制的细节,请看下一章。
