我正在尝试建立一个系统,其中用户发布并由其关注者点击的所有链接都以redis形式存储,以满足以下要求:
能够在一个时间范围内获得(例如,10%)大多数点击的链接(可以是今天,本周,所有时间或自定义)。
能够查询发布相同链接的所有用户。
由于我们已经使用了很多密钥,理想情况是我们将所有这些密钥存储在一个Redis密钥中。
如果需要,可以将值编码为JSON。
这是我到目前为止所得到的:
- 我使用单个Redis Hash,每个字段都是一个小时,因此在一天内,该哈希将包含24个字段。
- 在每个字段中,我存储一个编码的JSON,格式为:
array("timestamp1" => array($url1, $url2, ...)
, "timestamp2" => array($url3, $url4, ...)
, ..., ...);
- 完整的结构就是这个哈希:
[01/01/2010 00:00] => JSON(...),
[01/01/2010 01:00] => JSON(...),
....
这样,我可以在任何时间范围内获得任何网址的所有点击。
但是,我似乎无法重复使用此哈希来获取发布该URL的所有用户。
问题是:有没有更好的方法?
已于2011年7月30日更新:我目前正在将分钟,小时,天,周,月和年存储在相同的哈希值中。
因此,一次点击会立即存储在多个字段中: - 在分钟的领域(格式YmdHi) - 在小时的领域(格式YmdH) - 在当天的领域(格式Ymd) - 在本周的领域(格式YW) - 在本月的字段中(格式为Ym) - 在年度领域(格式Y)。
这样,当我试图获得一个特定的时间范围时,我只能访问必要的字段,而无需循环播放。
例如,如果我需要点击2011年7月26日20:00到07/28/2011 02:00,我只需要查询7个字段:2011年7月27日全天的1个字段, 7月26日20:00至23:00的4个小时,以及07/28的00:00至01:00的2个小时的小时数
答案 0 :(得分:2)
如果你放弃第三个要求,那就容易多了。很多人似乎认为你应该总是使用哈希而不是键,但这源于对在特定有限情况下使用哈希来提高性能的帖子的误解。
要获得点击次数最多的链接,请为每个小时或每天创建一个有序集,其值为链接,并且分数是使用ZINCRBY设置的点击次数。使用ZCARD和ZREVRANGEBYSCORE获得前10%。如果集合中包含系统中的所有链接,这是最简单的,但是如果需要,可以使用策略从集合中删除不太受欢迎的项目。
要让所有用户发布链接,请为每个链接存储一组用户。您可以使用JSON以及存储链接的密钥或哈希值来执行此操作,但是集合可以使更新和查询更容易。
答案 1 :(得分:0)
我建议使用一些存储桶策略,例如散列密钥或保留用户月份链接的记录,因为您无法控制数据结构的大小可能会增长多少。将有数百万用户访问特定链接。现在再次获取所有用户的详细信息,如果立刻抛出它将毫无用处。我相信可以做的是维护计数器或一些像当前状态一样的元数据,然后保持存档存储不在mem中。或者去寻找像GemFire这样的记忆网格