gpt4 book ai didi

redis - 如何从 Redis 中的集合中自动删除过期的 key ?

转载 作者:可可西里 更新时间:2023-11-01 11:20:59 28 4
gpt4 key购买 nike

比如说,我在 Redis 数据库中有 4 个键。 key 从现在起 10 秒后过期。我已经将 key 添加到一个集合中。当 key 过期时,它们实际上不再存在于数据库中(get 返回空值)。但是,键仍然是集合的成员。该集合将继续存在,直到从集合中删除键为止,此时它太有效地从数据库中消失了。

是否可以在 key 过期时自动从其所属的集合中删除 key ?

我正在考虑为每个键维护一个集合以维护它所属的集合(在键和集合之间建立有向图集合关系),然后注册键过期事件以在必要时删除集合成员。作为数据库的使用者,而不是作为内部的某种后台清理线程,这是很多开销。而且,这种方法将是清理集的“最大努力”,因为订阅过期事件的消费者代码可能会崩溃、无法收到通知、积压等。

我可能已经能够通过将键集建模为哈希集中的字段来避免任何欺骗,但我希望在实践中为每个键设置不同的到期 TTL。如果这是可能的,那又如何呢?

例如,这是我的一组“foo”键。

mine:0>set foo1 barA
OK

mine:0>set foo2 barB
OK

mine:0>set foo3 barC
OK

mine:0>set foo4 barD
OK

它们可以添加到一个集合中。

mine:0>sadd foo foo1 foo2 foo3 foo4
4

mine:0>smembers foo
1) foo1
2) foo3
3) foo4
4) foo2

然后 key 可能会过期...

mine:0>expire foo1 10
1

mine:0>expire foo2 10
1

mine:0>expire foo3 10
1

mine:0>expire foo4 10
1

mine:0>get foo1
NULL

mine:0>get foo2
NULL

mine:0>get foo3
NULL

mine:0>get foo4
NULL

mine:0>get foo5
NULL

此时键不存在,但集合存在,并且它引用了键。

mine:0>smembers foo
1) foo1
2) foo3
3) foo4
4) foo2

显式删除键将从集合中删除它们,然后在所有删除后使集合不存在。

mine:0>srem foo foo1
1

mine:0>srem foo foo2
1

mine:0>srem foo foo3
1

mine:0>srem foo foo4
1

mine:0>smembers foo
[nothing returned]

最佳答案

很简单!

首先要说明的是redis中的数据是没有任何引用关系的! foo1作为键和foo1作为集合中的元素是两个完全不同的东西,不同的数据在不同的内存地址,恰好存储相同的字符串“foo1”。

其次,我的方法不需要更改您的数据模型,只需更改您查询集合的方式即可。当你查询集合中的元素时,检查该键是否也作为单独的键存在于redis中,逻辑如下:

ArrayList getUnexpiredElementsInSet(String setKey){
ArrayList elements = smembers(setKey);
ArrayList resultArray = new ArrayList();
for (element in elements) {
if (exists(element)==false) {
srem(setKey, element);
}else {
resultArray.add(element);
}
return resultArray;
}

这样查询集合中的东西时,只会得到未过期的元素,过期的元素也会被清理。

以上只是向您展示基本逻辑的伪java代码,您需要将此逻辑包装在一个lua事务中。如果你不知道redis的lua特性,就学吧!它很棒,使 redis super 快速和强大。想要发挥redis真正的威力,lua是少不了的!引用Redis Lua

有些人担心脚本命令的性能损失。我可以向你保证那是不必要的。根据官方文档和我在实践中的经验,运行脚本完全没有性能损失。 这在理论上可以从很多方面理解:

  1. Redis 采用 Lua 而不是任何其他语言,因为 Lua 号称是最快的脚本语言。
  2. 每个脚本都可以存储在服务器端,客户端只需发送该脚本的 sha1 值及其输入参数即可调用,因此不存在长脚本的 I/O 负担。
  3. 通过发送存储脚本的sha1运行脚本时,脚本在redis服务器上预编译。因此,通过这种方式,运行包含在脚本中的命令与以普通旧形式运行这些命令本质上是相同的,除了脚本节省了大量耗时的 I/O 操作。难怪它 super 快。

关于redis - 如何从 Redis 中的集合中自动删除过期的 key ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32830347/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com