如何在redis中"扩展""HSET"子键?

aie*_*ven 88 hash redis

我需要使用redis散列中的所有密钥到期,这些密钥早于1个月.

Sup*_*upr 102

为了保持Redis简单,这是不可能的.

Quis Antirez,Redis的创造者:

嗨,这是不可能的,要么为该特定字段使用不同的顶级密钥,要么与提交的另一个字段一起存储过期时间,同时获取两者,并让应用程序了解它是否仍然有效当前时间.

  • @tObi 不同意。每个人都会以各种有缺陷且效率较低的方式来实现相同的功能。 (17认同)
  • @tObi 恕我直言,当我发现 Redis 中缺少我需要的某些功能时,这种情况经常发生 (8认同)
  • 这就是为什么redis是一款如此出色的软件。他们知道在哪里保持简单 (3认同)

hve*_*iga 10

Redis不支持使用TTL除顶级密钥以外的其他哈希,哈希将使整个哈希失效。如果使用分片群集,则可以使用另一种方法。这种方法并非在所有情况下都有用,并且性能特征可能与预期的有所不同。仍然值得一提:

当具有哈希时,该结构基本上如下所示:

hash_top_key
  - child_key_1 -> some_value
  - child_key_2 -> some_value
  ...
  - child_key_n -> some_value
Run Code Online (Sandbox Code Playgroud)

由于我们要添加TTL到子键,因此可以将其移到顶部键。要点是,密钥现在应该是hash_top_key和子密钥的组合:

{hash_top_key}child_key_1 -> some_value
{hash_top_key}child_key_2 -> some_value
...
{hash_top_key}child_key_n -> some_value
Run Code Online (Sandbox Code Playgroud)

我们{}故意使用该符号。这使所有这些键都落入相同的位置hash slot。您可以在这里阅读有关它的更多信息:https : //redis.io/topics/cluster-tutorial

现在,如果要执行相同的哈希运算,则可以执行以下操作:

HDEL hash_top_key child_key_1 => DEL {hash_top_key}child_key_1

HGET hash_top_key child_key_1 => GET {hash_top_key}child_key_1

HSET hash_top_key child_key_1 some_value => SET {hash_top_key}child_key_1 some_value [some_TTL]

HGETALL hash_top_key => 
  keyslot = CLUSTER KEYSLOT {hash_top_key}
  keys = CLUSTER GETKEYSINSLOT keyslot n
  MGET keys
Run Code Online (Sandbox Code Playgroud)

这里有趣的是HGETALL。首先,我们hash slot为所有孩子的钥匙找到了钥匙。然后,我们获取该特定项的密钥hash slot,最后获取值。我们在这里需要小心,因为可能有更多的n键,hash slot还有一些我们不感兴趣但它们具有相同键的键hash slot。实际上,我们可以编写Lua脚本来通过执行EVALor EVALSHA命令在服务器中执行这些步骤。同样,您需要考虑此方法在特定情况下的性能。

更多参考:

  • 这种方法比具有过期时间的简单键使用更多的内存。 (4认同)

小智 10

这在作为 Redis 分支的KeyDB中是可能的。因为它是一个 Fork,所以它与 Redis 完全兼容,并且可以作为替代品。

只需使用 EXPIREMEMBER 命令即可。它适用于集合、哈希和排序集合。

EXPIREMEMBER 键名子键 [时间]

您还可以使用 TTL 和 PTTL 查看过期时间

TTL 键名子键

更多文档可以在这里找到:https ://docs.keydb.dev/docs/commands/#expiremember


moj*_*ans 7

您可以在 redis 中使用Sorted Set来获取以时间戳为分数的 TTL 容器。例如,每当您将事件字符串插入集合中时,您都可以将其分数设置为事件时间。因此您可以通过调用获取任何时间窗口的数据 zrangebyscore "your set name" min-time max-time

此外,我们可以通过使用zremrangebyscore "your set name" min-time max-time删除旧事件来过期。

这里唯一的缺点是您必须从外部进程进行内务处理以保持集合的大小。


Mik*_*keZ 6

我们在这里讨论了同样的问题。

我们有一个 Redis 哈希,即哈希条目(名称/值对)的键,并且我们需要保存每个哈希条目的单独过期时间。

我们通过在写入哈希条目值时添加包含编码过期信息的 n 个字节的前缀数据来实现此目的,我们还将密钥设置为在写入值中包含的时间过期。

然后,在读取时,我们解码前缀并检查是否过期。这是额外的开销,但是,读取仍然是 O(n),并且当最后一个哈希条目过期时,整个密钥将过期。


小智 5

我提出的解决方案:

假设我想每 3 分钟过期一次:所以我将数据保存在 3 个字段 0 1 2 中,然后我将模块% 3 更改为当前时间(以分钟为单位)。

例如,如果模块 == 0 那么我只使用 1 2 和 0 我删除;然后它变为 1,所以我使用 2 和 0 并删除 1。

我没有使用它,也没有检查它,但我只是让你知道它是可能的