我正在尝试建立一个系统,在该系统中,用户发布并被他们的关注者点击的所有链接都存储在 redis 中,以满足以下要求:
能够在一个时间范围内(可以是今天、本周、所有时间或自定义)获得(例如,10%)点击次数最多的链接。
能够查询发布相同链接的所有用户。
由于我们已经使用了很多键,理想情况是我们将所有这些存储在一个 Redis 键中。
如果需要,可以将值编码为 JSON。
这是我到目前为止的想法:
-我使用单个 Redis 哈希,每个字段都是一个小时,因此在一天内,该哈希将包含 24 个字段。
-在每个字段中,我存储一个从数组编码的 JSON,格式为:
array("timestamp1" => array($url1, $url2, ...)
, "timestamp2" => array($url3, $url4, ...)
, ..., ...);
-完整的结构是这个hash:
[01/01/2010 00:00] => JSON(...),
[01/01/2010 01:00] => JSON(...),
....
这样,我可以获得任何时间范围内对任何 URL 的所有点击。
但是,我似乎无法重复使用此散列来获取发布该 URL 的所有用户。
问题是:有没有更好的办法呢?
2011 年 7 月 30 日更新:我目前将分钟、小时、天、周、月和年存储在同一个哈希中。
因此,一次点击会同时存储在多个字段中: - 在现场一分钟(格式 YmdHi) - 在现场工作一小时(格式 YmdH) - 在当天的现场(格式 Ymd) - 本周在外地(格式 YW) - 在月份字段中(格式 Ym) - 在当年的领域(格式 Y)。
就是这样,在尝试获取特定时间范围时,我只能访问必要的字段,而不会循环访问小时数。
比如我需要从07/26/2011 20:00到07/28/2011 02:00的点击,我只需要查询7个字段:1个字段为07/27/2011全天, 07/26 的 20:00 到 23:00 的时间有 4 个字段,然后 07/28 的 00:00 到 01:00 的时间还有 2 个字段
最佳答案
如果你放弃第三个要求,事情就会变得容易得多。许多人似乎认为您应该始终使用散列而不是键,但这源于对一篇关于在特定的有限情况下使用散列来提高性能的帖子的误解。
要获得点击次数最多的链接,请为每小时或每天创建一个排序集,值是链接,分数是使用 ZINCRBY 设置的点击次数。使用 ZCARD 和 ZREVRANGEBYSCORE 获得前 10%。如果集合包含系统中的所有链接,这是最简单的,尽管如有必要,您可以使用一些策略从集合中删除不太受欢迎的项目。
要让所有用户都发布链接,请为每个链接存储一组用户。您可以使用 JSON 和存储链接详细信息的键或散列来执行此操作,但集合使更新和查询更容易。
关于data-structures - Redis 数据结构存储所有链接的所有点击,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6827788/