【问题标题】:Redis ZRANGEBYSCORE returning empty setRedis ZRANGEBYSCORE 返回空集
【发布时间】:2015-07-10 11:17:11
【问题描述】:

这可能是愚蠢的事情..

在 redis 控制台中执行此操作

zincrby model 1 20140101
zincrby model 1 20141010
zincrby model 1 20141010

为什么会这样

zrangebyscore model 00000000 99999999 withscores
1) "20140101"
2) "1"
3) "20141010"
4) "2"

但这不是

zrangebyscore model 20140000 20149999 withscores

#> (empty list or set)

【问题讨论】:

    标签: redis


    【解决方案1】:

    ZRANGEBYSCORE 用于分数范围查找,而您正在使用您的成员(在第 3 个 sn-p 中)。从 1, 2

    在一些 cmets 后退后编辑

    通常,您需要权衡空间/时间,即更多 RAM 和更少 CPU,反之亦然,这实际上取决于您的性能和数据大小要求。通常我会尝试为每个需要跟踪的每个聚合级别的模型/事件使用一个排序集。密钥过期很有用,但有时也需要手动从排序集中删除成员。

    IIUC,您需要每个型号的每日计数器,因此按照您的初始设计,我的“模式”可能是:

    Sorted set key name pattern: <model>:daily
                                   |
                                   +- Member value: <day timestamp at 12AM UTC>
                                   +- Member score: <count>
    

    使用 ZINCRBY 增加今天的点击率:

    ZINCRBY <model>:daily 1 <today's timestamp at 12AM UTC>
    

    获取日期的点击次数:

    ZSCORE <model>:daily <date timestamp at 12AM UTC>
    

    注意事项:

    1. 无法使用这种方法轻松地确定日期范围,因为您的分数会保持计数。您基本上需要执行多个 ZSCORE (O(log(N))),循环遍历范围内的每个日期。
    2. 您可以保留额外的滚动或静态聚合以加快常用范围的访问速度。
    3. 您必须手动“使”较旧的集合成员“过期”以进行管理。

    允许范围的另一种方法是设置以下内容:

    Sorted set key name pattern: <model>:daily
                                   |
                                   +- Member value: <day timestamp at 12AM UTC>:<count>
                                   +- Member score: 0
    

    在这里,您可以使用 ZRANGEBYLEX 获取日期范围,但由于时间戳和计数是连接的,您必须在客户端或使用 Lua 进行一些处理才能获取计数(ZSCORE 将始终返回 0)或增加它(你不能再使用 ZINCRBY)。

    【讨论】:

    • 对于时间序列数据使用redis排序集,使用(如果我错了,请纠正我)时间戳作为分数不是更好吗?我到处阅读人们推荐的内容,并检索数据,在所需的时间范围内使用 ZRANGEBYSCORE。这里的东西对我来说是倒退的......
    • 有序集合中的每个元素都有两个属性——唯一的成员值和分数。时间序列通常使用分数来保持时间戳(纪元),而成员就是要添加的内容(通常,成员是由 : 之类的东西构建的,以使其独一无二)。您正在做的是使用时间戳作为成员,并且分数会增加。这意味着您使用的 ZSET 为时间戳保留分数 (1, 2, ...) - 如果您尝试解释您正在尝试做什么可能会更好:)
    • 应用程序中每个模型的基本分析。我想计算每个模型 ID 的访问/事件,并能够按日期获取该数据。所以,在这里(stackoverflow.com/questions/26174150/…)我被推荐使用排序集,就像其他地方也推荐的那样,但它似乎只有在当前日期的计数将使用不同的计数器时才有用,然后每天使用ZADD,总计数为成员,时间为得分。您建议如何实施?
    • 谢谢!排序集方法是否比使用带有年度键和 365 个值(每天)的哈希更可取,所以我可以 HINCRBY 用于计数器,并在范围之间获取我可以做 HMGET(也是 O(N),但我可以做到与服务器端一起生成日期范围)。根据support.redistogo.com/kb/info/…,它的大小差不多(别担心,因为你是 garantia,我就在 redislabs ;)
    • 一点也不担心,无论如何都会有所帮助 :) 散列在 RAM 方面可能会更有效,但在使用分数进行计数时,使用排序集,您将立即获得最高 - k 功能。归根结底,一切都是关于您尝试做的事情...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 2015-12-26
    • 1970-01-01
    • 2021-01-14
    • 2010-09-25
    • 2015-07-04
    相关资源
    最近更新 更多