到点就自动忘记某个键的过期机制。

Redis TTL 让每个键自带时钟

Redis 过期机制回答的是一个键什么时候应当停止可见,而不是整个服务最多使用多少内存。截止时间属于键,后续命令可能保留、替换或者移除它。因此,可靠地使用 TTL,既要检查首次写入,也要覆盖更新路径。看到写命令成功,不能证明之前设置的截止时间仍然存在,更不能直接推断数据最终会按原计划消失。 截止时间不是自动滑动计时器 EXPIRE 使用秒,PEXPIRE 使用毫秒。Redis 将过期信息保存为绝对 Unix 时间戳,所以服务器停止运行期间,时间仍然继续流逝。系统时钟必须稳定,跨机器恢复数据时尤其需要注意时钟差异。它不是独立于系统时间变化的单调时长承诺。下面的实验只使用正常流逝的时间,不调整本机系统时钟。 GET 不会刷新过期时间。INCR 这类原地修改保留键已有的超时;普通成功的 SET 则替换值,并清除原来的超时。SET KEEPTTL 可以保留原期限,再次显式设置过期命令则会改变截止时间。需要滑动会话的应用必须主动实现续期策略,不能以为用户每次读取数据都会自然延长访问窗口。 当值和初始寿命属于同一次操作时,应使用 SET EX 或 SET PX 一起写入。分成 SET、EXPIRE 两条命令,会留下一个值已经存在、期限却尚未写入的失败窗口。客户端如果恰好在两条命令之间崩溃,就可能留下持久条目。这是写入协议缺陷,不是后台过期周期执行得太慢,调整清理频率也修复不了它。 检查真正存在的状态 TTL 返回剩余秒数;键存在但没有过期时间时返回 -1,键不存在时返回 -2。PTTL 提供毫秒分辨率,PEXPIRETIME 则返回绝对截止时间。要验证一次读取有没有续期,比较绝对期限比比较两次倒计时更可靠,因为两条查询之间时间正常流逝,本来就可能让剩余数值减少。查询结果只是当时的快照,不保证键一定能存活到那个时刻。 EXPIRE NX 只在没有期限时添加期限。GT 只接受更晚的截止时间,其中持久键被当成无限寿命处理。PERSIST 则显式移除过期设置。调用方需要检查命令返回的结果,不能把“命令被接受”理解成“条件成立且状态已经改变”。相对过期时间为零或负数时,键会立即被删除,并不是改成永久保存的另一种写法。 坏掉的样子 被动过期在访问时检查截止时间,主动过期负责处理那些过期后没有再被访问的键。物理清理延迟,不等于普通主节点 GET 可以持续交付已经过期的值。反过来,条目被移除,也不保证分配器马上把页面交还操作系统。读取可见性、数据结构清理与进程 RSS 是不同观察对象,不能只看其中一个就替其他两个下结论。 ...

六月 29, 2027 · 2 分钟 · XB Field Notes