我有许多分类分布。分类分布是指从一组k个事件中抽取事件的概率。我需要能够非常快速地访问事件的概率。
存储分类分布的一种方法是使用排序集在Redis中。每个键索引一个单独的分布,排序集的每个成员都是一个特定事件,每个分数是您看到该事件的次数。对于每个密钥(分发),您还将存储该分发中每个事件的计数总和,以便您可以正确地进行规范化。
我想问的问题是:如果概率随时间变化,那么存储这些数据的好方法是什么?我基本上希望能够忘记旧的观察 - 即以某个规则的间隔递减每个键的得分和归一化常数。
使用上面的redis方法,我可以每隔d分钟运行一次cron作业,迭代每个分布并减少zscore和规范化常量中的每个计数。然而,这似乎有点不对(我确信我的妈妈告诉我永远不要迭代KEYS *),所以我想知道是否还有其他人更全面地解决了这个问题?
答案 0 :(得分:1)
我猜你觉得错的是:
之前我没有做过这样的事情,但是如果你能够节省更多的存储空间,我会想到一个解决方案。
我们的想法是定期存储时间戳快照队列。每个快照表示您的分配中该时间间隔内的事件计数。如果要使分发中的旧概率过期,可以从列表中弹出过期的快照并相应地减少ZSET。
更具体地说,您需要:
HSET
| S k > E |
用于存储事件数据。对快照中的所有事件重复此操作。RPUSH SNAPSHOTS <timestamp>:
S k LPOP
SNAPSHOTS列表,解码时间戳并验证是否过期。LPUSH
它会重新进入SNAPSHOTS列表并完成,直到下一个到期时间为止。否则... HKEYS
S k 的结果,解码每个事件键 q(E),得到相应的计数,然后按该数量减少适当的ZSET和归一化因子。所需的额外存储量取决于快照的长度和到期时间间隔以及每个快照时间间隔内发生的不同事件的数量。
在最坏的情况下,每个快照中都会显示每个分发和事件,因此这对错误因素#1没有帮助。乐观地说,在任何快照中都会表示适当小比例的分布和/或事件,并且到期过程的效率将会提高。但即使在最坏的情况下,这也将解决错误因素#2,因为每次到期的cron作业运行时,最近发生的事件都不会在您的发行版中无条件地减少。