如何计算匹配模式的键数?
Posted
技术标签:
【中文标题】如何计算匹配模式的键数?【英文标题】:How to count the number of keys matching a pattern? 【发布时间】:2013-12-23 11:41:46 【问题描述】:我怎样才能找到具有匹配模式的所有键的计数。
例如,有两个键 abc:random-text-1
和 abc:random-text-2
。这里的常见模式是abc:
。所以,这里的计数是 2。
如何在 redis 中做到这一点?
【问题讨论】:
在生产环境中计算 Redis 中的键永远是个坏主意。 【参考方案1】:来自here:
eval "return #redis.pcall('keys', 'abc:*')" 0
这不是 O(1),但至少计数是在服务器端完成的。
【讨论】:
这正是我想要的。 请注意,这仍然使用阻塞的keys
命令,这可能会导致大型实例的性能中断。
600K 键 2 秒,足够快
这是 O(n),其中 n 是键的数量。对数百万个键来说真的很糟糕!
@AnatoliiStepaniuk 我不知道。每个人都有他的理由。但是说“从不(!!)”是绝对的陈述。正确的做法是解释你的推理,让人们在需要选择的时候自己决定。 (我认为这个答案是在更好的选择可用之前写的)。【参考方案2】:
免责声明我希望这个旧答案没有损坏任何拥有数百万个密钥的生产系统。如果你出于某种原因仍然想统计生产中redis的匹配键,better use scan with a match pattern。
如果你只是用 KEYS 搜索,用你的 redis 客户端,你会得到一个所有匹配键的数字列表,对吧?
例如
KEYS abc:*
会给你
1) abc:random-text-1
2) abc:random-text-2
或者您可以运行以下命令:
./redis-cli KEYS "abc:*" | wc -l
你会得到2
作为输出。
【讨论】:
这正是我所需要的!谢谢 如果一个人拥有数百万个密钥呢? 这是一个旧答案。我实际上应该在这里添加一个免责声明。所以不要在具有数百万个密钥的生产设置中使用它。最好将 SCAN 光标与 MATCH 一起使用 你不应该在生产环境中运行这个命令,这是阻塞命令,如果你运行这个命令,所有的请求都会被饿死,如果这个命令运行的时间更长,可能会超时。 谢谢!一年前,我也注意到并在顶部添加了免责声明。当我 6 多年前回答时,我不认为有人可能会在生产环境中运行它。【参考方案3】:从命令行,redis-cli --scan --pattern 'abc:*' | wc -l
【讨论】:
您的答案很完美,但需要详细解释,例如。您的 redis 密钥 127.0.0.1:6379> keys abc* 1) "abc123" 2) "abc456" 3) "abc234" 现在尝试访问:从命令行, redis-cli --scan --pattern 'abc* ' | wc -l 响应如下: localhost@username~$ redis-cli --scan --pattern 'abc*' | wc -l 3 这应该是公认的答案。需要版本 >= 2.8.0 的 redis 我是否正确理解所有匹配的记录都被提取到客户端?【参考方案4】:考虑到性能,我不建议你使用KEYS
警告:将 KEYS 视为仅应在 非常小心的生产环境。它可能会破坏性能 当它针对大型数据库执行时。该命令旨在 用于调试和特殊操作,例如更改键空间 布局。不要在常规应用程序代码中使用 KEYS。如果你是 寻找一种在您的键空间子集中查找键的方法,请考虑 使用集合。
如果您的 redis 版本 > 2.8.0,我建议您考虑 scan。但这取决于您要使用的数据类型。
这是来自redis doc的一个简单示例:
redis 127.0.0.1:6379> sadd myset 1 2 3 foo foobar feelsgood
(integer) 6
redis 127.0.0.1:6379> sscan myset 0 match f*
1) "0"
2) 1) "foo"
2) "feelsgood"
3) "foobar"
【讨论】:
如何使用扫描来计算密钥? 您可以阅读官方文档:redis.io/commands/scan。或谷歌它:***.com/questions/33166812/… 好吧,谷歌搜索把我带到了这里 :) 如果你可以编辑你的答案以包含一个简单的命令,使用scan
来计算与模式匹配的键的数量,那将会很有帮助。
@Joshua 看scan api 好像不能一次性找到count总数。
如果您想使用 SCAN 计算键,您需要在每次迭代中存储键,并使用您喜欢的过滤重复项的方法(SCAN 不保证值只会出现一次),可能在允许快速查找现有值的数据结构中。对于巨大的密钥集,这将是不切实际的,因为您需要将所有密钥存储在内存中,直到 SCAN 完成,因此您需要考虑保留一个辅助密钥作为您在 SET/DEL 上更新的计数器,或将您的数据存储在易于计数的类型中(例如,在 Redis 哈希中)。【参考方案5】:
如果它是一次性的,您可以按照 x_maras 的描述使用 KEYS,但您不应该在代码中使用它,因为每次调用 KEYS 时都会扫描整个数据库中的每个键。
如果你想经常这样做,没有你写的那样“好”的方法,因为扫描每个键总是相当低效(即使使用 SCAN,因为它会做与 KEYS 相同的事情只是以更安全的方式)。
但是,如果提前知道您需要的模式,您可以保留一组与该模式匹配的每个键。
SET abc:random-text-1 "blah"
SADD patterns:abc abc:randomtext-1
SET abc:random-text-2 "more blah"
SADD patterns:abc abc:randomtext-2
SCARD patterns:abc
// (integer) 2
SORT patterns:abc BY nosort GET *
// 1) "blah"
// 2) "more blah"
【讨论】:
以上是关于如何计算匹配模式的键数?的主要内容,如果未能解决你的问题,请参考以下文章