Redis:KEYS * 的结果如何排序?

5

我有一个非常简单的php redis应用程序,它在某些事件中创建键。所有键都只是计数器,并且具有24小时的过期时间。基本上,每个键都有一个滚动窗口,为了收集一些统计信息,持续24小时。

if ($redis->exists($key)) {
    $redis->incr($key); 
}
else {
    $redis->set($key, '1');
    $now = time(); // current timestamp
    $redis->expireAt($key, $now + 86400);
}

当我使用$list = $redis->keys("*");(或在redis-cli控制台中使用keys *)提取所有键的概述时,我会怀疑它们按创建日期的时间顺序排序。然而,实际情况并非如此。它们既不按字母顺序排序,也不按值排序...因此我的问题是,这个列表是如何排序的?
1个回答

12
首先,不要使用 keys *,它是一个调试函数,不适合在生产环境中使用,可能会导致服务器崩溃... 如果您需要以安全的方式枚举DB中的所有键,请使用带有LIMITSCAN函数。
无论如何,keysscan的结果都没有按任何方式排序,结果的顺序与redis哈希表的内部内存结构相关。
关于您的php脚本,只需运行单个命令即可完成,无需使用 exists set expireat

SET key 1 EX 86400 NX

EX 86400表示从现在开始86400(1天)秒后到期

NX表示仅在键不存在时创建键。

如果此命令返回(nil),则运行常规的INCR key,这意味着该键已经存在。另外,INCR 命令不会删除您的过期设置。

1
一条几乎完美的回复——扼杀了一个恶劣的模式,提供了问题的答案,并教授了正确的Redis使用方法——如果可以的话,我会点赞两次。最后再附上一个伪PHP示例,就更加完美了;p - Itamar Haber
嗨,Itamar,我不知道他在使用什么客户端:) 顺便说一句,在特拉维夫北部偶尔喝杯咖啡会很好,我们是邻居=) - h0x91B
客户方面的观点很中肯。如果没有甜点,我很乐意为此买单 - 联系我,我们会让它发生。 - Itamar Haber
@h0x91B 我将使用命令 hkeys keyname 获取与 keyname 对应的所有 字段,那么这些 字段 是按顺序排列的吗?它们是按照什么排序的呢? - Pychong
@Pychong 基本上,以上所有内容都适用于 HSET,如果你的 HSET 很大,你可以使用 HSCAN。 在底层,小的 HSETs 存储在内存中作为 zip-list,因此您将按照添加它们的相同顺序获取密钥。但是,在超过 hash-max-ziplist-value 512hash-max-ziplist-entries 64 的阈值后,HSET 将转换为真正的哈希表,然后键将以随机顺序返回给您。 更多信息:https://redis.com/ebook/part-2-core-concepts/01chapter-9-reducing-memory-use/9-1-short-structures/9-1-1-the-ziplist-representation/ - h0x91B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接