- 用法
-
EXPIRE key seconds [ NX | XX | GT | LT ]
- 复杂度
- O(1)
- 始于
- 1.0.0
- ACL 类别
- @keyspace, @write, @fast
NX
-- 仅当 key 没有过期时间时才设置过期时间XX
-- 仅当 key 已存在过期时间时才设置过期时间GT
-- 仅当新的过期时间大于当前过期时间时才设置过期时间LT
-- 仅当新的过期时间小于当前过期时间时才设置过期时间ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP
= 20 - 每个 DB 循环的键数量。ACTIVE_EXPIRE_CYCLE_FAST_DURATION
= 1000 – 快速循环的最大持续时间(微秒)。ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC
= 25 – 慢循环期间最大 CPU 使用百分比。ACTIVE_EXPIRE_CYCLE_ACCEPTABLE_STALE
= 10 – 内存中可容忍的过期键最大百分比。ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP + (ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP / 4 * (effort - 1))
ACTIVE_EXPIRE_CYCLE_FAST_DURATION + (ACTIVE_EXPIRE_CYCLE_FAST_DURATION / 4 * (effort - 1))
ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC + (2 * (effort - 1))
ACTIVE_EXPIRE_CYCLE_ACCEPTABLE_STALE - (effort - 1)
为 key
设置超时时间。超时时间到期后,该 key 将自动删除。在 Valkey 术语中,带有关联超时的 key 通常被称为易失性的。
超时时间只会被删除或覆盖 key 内容的命令清除,包括 DEL
、SET
、GETSET
以及所有 *STORE
命令。这意味着所有概念上改变 key 中存储的值而不替换为新值的操作,都将保持超时时间不变。例如,使用 INCR
递增 key 的值,使用 LPUSH
将新值推入列表,或使用 HSET
更改哈希的字段值,所有这些操作都不会影响超时时间。
超时时间也可以通过使用 PERSIST
命令清除,从而将 key 恢复为持久化 key。
如果 key 使用 RENAME
重命名,则关联的生存时间会转移到新的 key 名。
如果 key 被 RENAME
覆盖,例如现有的 key Key_A
被 RENAME Key_B Key_A
调用覆盖,则无论原始 Key_A
是否关联了超时时间,新的 key Key_A
都将继承 Key_B
的所有特性。
请注意,调用 EXPIRE
/PEXPIRE
时指定非正数超时,或调用 EXPIREAT
/PEXPIREAT
时指定过去的时间,将导致 key 被删除而不是过期(相应地,发出的key 事件将是 del
,而不是 expired
)。
选项
EXPIRE
命令支持一组选项
对于 GT
和 LT
,非易失性 key 被视为无限 TTL。GT
、LT
和 NX
选项是互斥的。
刷新过期时间
可以使用已设置过期时间的 key 作为参数调用 EXPIRE
。在这种情况下,key 的生存时间会更新为新值。这有很多有用的应用,例如在下面的导航会话模式部分中记录的示例。
对于已设置超时时间的 key,EXPIRE
将返回 0 且不更改超时时间。
示例
127.0.0.1:6379> SET mykey "Hello"
OK
127.0.0.1:6379> EXPIRE mykey 10
(integer) 1
127.0.0.1:6379> TTL mykey
(integer) 10
127.0.0.1:6379> SET mykey "Hello World"
OK
127.0.0.1:6379> TTL mykey
(integer) -1
127.0.0.1:6379> EXPIRE mykey 10 XX
(integer) 0
127.0.0.1:6379> TTL mykey
(integer) -1
127.0.0.1:6379> EXPIRE mykey 10 NX
(integer) 1
127.0.0.1:6379> TTL mykey
(integer) 10
模式:导航会话
假设你有一个 Web 服务,你对用户最近访问的最新 N 个页面感兴趣,条件是每个相邻页面浏览之间的时间间隔不超过 60 秒。从概念上讲,你可以将这组页面浏览视为用户的导航会话,其中可能包含关于他或她当前正在寻找哪种产品的信息,以便你可以推荐相关产品。
你可以使用以下策略在 Valkey 中轻松建模此模式:每当用户进行页面浏览时,你都调用以下命令
MULTI
RPUSH pagewviews.user:<userid> http://.....
EXPIRE pagewviews.user:<userid> 60
EXEC
如果用户空闲超过 60 秒,key 将被删除,并且只有后续页面浏览时间差小于 60 秒的才会被记录。
这个模式可以很容易地修改为使用 INCR
代替 RPUSH
来使用计数器。
附录:Valkey 过期
带有过期时间的 key
通常 Valkey key 在创建时没有关联生存时间。该 key 将永远存在,除非用户通过显式方式删除它,例如使用 DEL
命令。
EXPIRE
系列命令能够为给定 key 关联一个过期时间,代价是 key 会使用一些额外的内存。当 key 设置了过期时间后,Valkey 会确保在指定时间到期时删除该 key。
key 的生存时间可以使用 EXPIRE
和 PERSIST
命令(或其它严格相关的命令)更新或完全移除。
过期精度
过期误差为 0 到 1 毫秒。
过期和持久化
key 的过期信息以毫秒为单位存储。这意味着即使 Valkey 实例不活动,时间也在流逝。
为了使过期正常工作,计算机时间必须保持稳定。如果你从两台时钟严重不同步的计算机移动 RDB 文件,可能会发生一些奇怪的事情(例如所有加载的 key 在加载时就已过期)。
即使是运行中的实例也会一直检查计算机时钟,所以例如你设置一个 key 的生存时间为 1000 秒,然后将你的计算机时间向前调整 2000 秒,这个 key 将会立即过期,而不是持续 1000 秒。
Valkey 如何回收过期 key
Valkey 通过两种方式回收过期 key:访问时和在后台(即“主动过期 key”循环中)。访问时过期是指客户端尝试访问一个已超时过期的 key。该 key 在此次访问尝试时被删除。
仅依靠访问时过期是不够的,因为有些过期 key 可能永远不会再被访问。为了解决这个问题,Valkey 使用了名为“主动过期 key”工作的后台过期算法。该算法是自适应的:如果需要回收的过期 key 较少,它会尝试使用较少的 CPU。否则,它会变得更激进,尝试通过在更短的运行时间内回收更多 key 来释放更多内存,但会使用更多 CPU。
其工作原理如下
Valkey 缓慢扫描键空间以识别和回收过期键。这种“慢周期”是收集过期键的主要方式,并以服务器的赫兹频率(通常为 10 赫兹)运行。在慢周期期间,Valkey 允许内存中过期的键不超过 10%,并尝试最大使用 25% 的 CPU 功率。如果用户更改了主动过期键的配置,这些默认值会进行调整。
如果在慢周期后过期 key 的数量仍然很高,则主动过期 key 工作将进入“快周期”,尝试做更少的工作但更频繁。快周期运行时间不超过 1000 微秒,并以相同的间隔重复。在快周期期间,一旦数据库中已过期 key 的数量估计低于 10%,就会中断对每个数据库的检查。这样做是为了避免做太多工作却只获得太少的内存。
您可以在配置文件中通过 active-expire-effort
参数修改主动过期键工作,最大值为 10
。默认的 active-expire-effort
值为 1
,其基础值如下所示
更改 active-expire-effort
值会导致内存中容忍的过期键百分比降低。然而,这会导致更长的循环和更高的 CPU 使用率,这可能会引入延迟。
要计算新值,请使用以下公式
其中 ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP
、ACTIVE_EXPIRE_CYCLE_FAST_DURATION
、ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC
和 ACTIVE_EXPIRE_CYCLE_ACCEPTABLE_STALE
是基值,effort
是指定的 active-expire-effort
。
复制链接和 AOF 文件中过期时间的处理方式
为了在不牺牲一致性的情况下获得正确的行为,当 key 过期时,将在 AOF 文件中生成一个 DEL
操作,并传播到所有连接的副本节点。通过这种方式,过期过程集中在主实例中,从而避免了一致性错误的发生。
然而,虽然连接到主实例的副本不会独立地使 key 过期(而是等待来自主实例的 DEL
命令),它们仍然会获取数据集中存在的过期key的完整状态,因此当副本被选为主实例时,它将能够独立地使 key 过期,完全作为主实例运行。
RESP2/RESP3 回复
以下之一
历史
版本 | 变更 |
---|---|
7.0.0 | 新增选项: |