我的网站上有一个简单的每日点击计数器,我想使用Redis作为数据存储区。
仅仅因为redis有一个过期,我不必设置一个cron来清除数据。另外我想尝试一下。
我以网址存储每日点击次数。
如何存储每日点击数据,然后让它们在当天结束时过期。
例如:
incr today:www.google.com >> 1 incr today:www.google.com >> 2 incr today:www.google.com >> 3 incr today:www.yahoo.com >> 1 incr today:www.yahoo.com >> 2
我如何让这些计数器在一天结束时到期? 如果我过期,它会重置计数器。
我觉得我的思维过程已关闭。我倒退了吗?
答案 0 :(得分:7)
你需要使用当前日期作为关键而不是“今天”。
为当前日期设置哈希值,每个url是该哈希值中的键。您的更新将是
HINCRBY 101021 www.google.com 1
并且您可以使用DEL命令在您不再想要保留数据时删除整天的哈希值 - 可能会设置一个手动触发的脚本,该脚本会在1到2个月之间调用DEL。
设置哈希的到期可能也会有效但我还没有尝试过 - 每天使用不同的密钥意味着你不依赖于在精确时间发生的到期,就像你使用“今天”密钥一样
答案 1 :(得分:2)
另一种选择是使用redis> = 2.1.3。从该版本开始,expire以您想要的方式工作。我正在使用2.1.5(来自git)来做同样的事情。我使用expire和类似Tom描述的方法。我将日期放在密钥中,然后设置到期日。使用redis> = 2.1.3,您可以设置在递增的密钥上过期而不重置计数器。
两者的原因是a)我存储超过一天b)如果过期的密钥仍然存在,无论出于何种原因我今天获取统计数据时都不会查询它们。例如,散列:具有键YEAR的MONER:MONTH:DAY:URL递增,并且为今天+ 3天设置过期。像魅力一样。
答案 2 :(得分:1)
我最近为我的应用中内置的分析做了解决方案:
incr www.google.com 1
然后每晚,在一个cron工作:
getset www.google.com 0
getset以原子方式返回值并将其设置为新值,这会重置您的计数器而不会错过任何一次点击。
我也碰巧:
lpush yearly:www.google.com <value from getset>
ltrim yearly:www.google.com 0 364 (this is optional)
这会将“昨晚的”值放到列表中。可选择修剪列表以存储最多一年的值。 (这在做60分钟的迷你线时非常有效)
答案 3 :(得分:0)
使用当前日期时,建议使用更直接的选项。我所做的是使用年月日作为关键。但是,我不是使用哈希,而是通过将页面附加到日期作为关键字来简化问题。
例如:
INCR 20110425:www.google.com INCR 20110424:www.yahoo.com ... INCR 20110426:www.google.com
为了更容易检索信息,我在适当的时候使用另一个解决方案将信息存储在有序集合中。
例如:
$rank = ZRANK hits:www.google.com 20110425 ZADD hits:www.google.com ($rank + 1) 20110425
通过此变体,您只需询问以下内容即可获得www.google.com的所有匹配:
ZRANGE hits:www.google.com 0 -1
或
ZREVRANGE hits:www.google.com 0 -1
或
SORT hits:www.google.com ...
希望这是一些帮助