ERM redis runtime_error ai_generated true

键过期竞态条件:TTL 已更新但键已过期

ERR Key expiry race condition: TTL updated but key already expired

ID: redis/key-expiry-race-condition

其他格式: JSON · Markdown 中文 · English
85%修复率
80%置信度
1证据数
2023-11-10首次发现

版本兼容性

版本状态引入弃用备注
6.0 active
7.0 active
7.2 active

根因分析

多个客户端同时更新 TTL 和键值时发生竞态条件,导致键在 TTL 更新生效前已过期。

English

A race condition occurred when multiple clients simultaneously update TTL and key value, causing the key to expire before the TTL update takes effect.

generic

官方文档

https://redis.io/docs/latest/commands/expire/

解决方案

  1. 使用 EVAL 执行脚本:'local val = redis.call("GET", KEYS[1]); if val then redis.call("SET", KEYS[1], ARGV[1]); redis.call("EXPIRE", KEYS[1], ARGV[2]); return 1 else return 0 end'。
  2. 在 GET 前使用 WATCH 监视键,然后使用 MULTI/EXEC 更新 TTL。如果 WATCH 触发,则重试。

无效尝试

常见但无效的做法:

  1. 50% 失败

    SET with EX still has a race if key is deleted by another client before EXPIRE.

  2. 60% 失败

    Redis transactions are not atomic for conditional operations; EXPIRE may still fail if key expires during transaction.

  3. 75% 失败

    Race condition persists; repeated failures under high concurrency.