【问题标题】:Redis Sorted Set ZSCAN order of itemsRedis Sorted Set ZSCAN 项目顺序
【发布时间】:2020-07-22 12:27:09
【问题描述】:

我在 Redis 中有一个带有时间戳的排序集,并且与该集的不同类型的关系存储在一起。

示例数据集解释如下:

zadd s1 10 rel1:val1  
zadd s1 15 rel1:val2
zadd s1 12 rel1:val3  

zadd s1 10 rel2:v1  
zadd s1 12 rel2:v2
zadd s1 5 rel1:v3  

我要从集合中寻找 rel1 或 rel2 的顶部元素,如果我尝试单独存储它们,我将以许多键结尾,我想避免这些。

我尝试了 ZSCAN,结果按分数按升序排列,如下所示

localhost:6379> zscan s1 0 match "rel1*" count 10
1) "0"
2) 1) "rel1:v3"
   2) "5"
   3) "rel1:val1"
   4) "10"
   5) "rel1:val3"
   6) "12"
   7) "rel1:val2"
   8) "15"

如果我在 -ive 中对时间戳进行评分,我会得到预期的顶部元素结果

localhost:6379> zadd s1 -10 rel1:val1
(integer) 0
localhost:6379> zadd s1 -20 rel1:val2
(integer) 0
localhost:6379> zadd s1 -30 rel1:val3
(integer) 0
localhost:6379> zscan s1 0 match "rel1*" count 10
1) "0"
2) 1) "rel1:val3"
   2) "-30"
   3) "rel1:val2"
   4) "-20"
   5) "rel1:val1"
   6) "-10"
   7) "rel1:v3"
   8) "5"

我的问题可以转达这个结果,并相信结果总是按 ZSCAN 的升序排列。

我不能使用 ZREVRANGE 或 ZRANGE 命令,因为我必须通过 MATCHING 成员获得前 n 个项目。

【问题讨论】:

  • zset 的文档说明如下,似乎成员是根据分数排序的。 [github.com/antirez/redis/blob/unstable/src/t_zset.c] ` * 将元素添加到将 Redis 对象映射到分数的哈希表中。 * 同时元素被添加到一个跳过列表映射分数 * 到 Redis 对象(所以对象在这个“视图”中按分数排序)。 ` 我可以假设 ZSCAN 将始终按分数扫描元素吗?

标签: redis


【解决方案1】:

没有。你不能依赖它。订单未定义。

正如我们所知,ZSET 是通过 dict/hash 和 skiplist 实现的。 ZSCAN 命令扫描字典,而不是跳过列表。由于dict是无序的,所以扫描结果的顺序是不确定的。

【讨论】:

    【解决方案2】:

    如果您使用像给定数据这样的小样本数据,您可能会得到正确排序的结果。但不要相信它。

    正如@for_stack 所说,ZSCAN 不保持结果的顺序。你可以生成大量的样本来测试它,然后你会发现。您必须切换到 ZRANGE、ZREVRANGE 或其他方式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-22
      • 1970-01-01
      • 1970-01-01
      • 2014-06-01
      • 2015-07-17
      相关资源
      最近更新 更多