Redis缓存过期时间远短于设定值,180秒有效期仅5秒就失效
问题原因分析
- 内存淘汰策略触发
当Redis实例内存占用达到配置的maxmemory上限时,会按照设置的淘汰规则清理数据。如果采用的是volatile-lru(清理最近最少使用的带过期时间的键)、volatile-ttl(优先清理剩余存活时间更短的带过期时间的键)这类策略,还未到过期时间的键也会被提前清理。你将过期时间调整为3600秒后问题消失,大概率是更长的过期时间降低了键在volatile-ttl策略下的淘汰优先级,没有被优先清理。 - 其他业务逻辑误修改
排查是否有异步任务、定时脚本或者其他业务分支,对同一个key执行了expire/pexpire命令,或者发起了覆盖写入的set操作,误将过期时间改成了5秒,覆盖了初始设置的180秒。 - redis-py依赖包版本bug
部分老旧版本的redis-py存在set方法参数处理的异常,比如错误将ex参数识别为毫秒级的px参数,或者存在数值解析错误。可以在写入后立刻调用client.ttl(key)查看实际生效的过期时间,确认是否和预期的180秒一致。 - 定制化Redis服务的特殊规则
如果使用的是云厂商托管的Redis服务或者经过二次开发的Redis实例,可能存在针对短过期时间键的特殊清理逻辑,或者全局的过期时间覆盖规则,也会导致该异常。
排查步骤
- 写入缓存后立刻执行
print(client.ttl(key)),如果返回的剩余过期时间远小于180,说明写入阶段就没有正确设置过期时间,优先检查代码参数逻辑,升级redis-py到最新稳定版后重试。 - 执行
config get maxmemory和config get maxmemory-policy查看Redis的内存配置,再通过info stats查看evicted_keys指标的增长情况,如果该指标持续上涨,说明存在频繁的键淘汰,需要扩容Redis内存或者调整淘汰策略。 - 测试环境下可以执行
monitor命令捕捉所有对该key的操作,确认是否有其他来源的修改、删除、调整过期时间的命令执行。
内容的提问来源于stack exchange,提问作者Prabhakar Shanmugam
相关产品推荐
相关产品推荐

