PHP Redis(predis)计数器,具有唯一的当前查看器

时间:2014-03-23 22:05:34

标签: php redis counter

我想知道如何使用Redis实现一个唯一的访问者计数器,超时为1小时。我有一个小网上商店,我想展示有多少人正在查看当前的文章。什么是最好的方式?我正在使用Predis

非常感谢

1 个答案:

答案 0 :(得分:0)

您需要做两件事:

  • 为每位访问者(他们are many ways to do it
  • 生成唯一ID
  • 使用Redis SETZSET存储这些ID并添加过期机制。

方法#1:SET + SCARD + EXPIRE

<强>解决方案

SET名称可能类似于[article_id]:[current_hour_timestamp],每当您SADD内有访客ID时,请执行EXPIRE。每一套都会在一段时间后过期。

使用SCARD [article_id]:[current_hour_timestamp]了解有多少访问者在线

备注

如果您愿意,密钥可以是[article_id]:[current_hour_timestamp]articles:[article_id]:readers:[current_hour_timestamp]之类的内容......

每隔一小时开始,SET将为空,这不是你想要的。

方法#2:ZSET + ZCARD + cron

<强>解决方案

每次访问者阅读打开文章时发送ZADD [article_id]:readers [expiry_time] [visitor_id],如果重新加载页面无关紧要,expiry_time将会更新。

expiry_time是我们考虑访问者留下文章时的时间戳。

设置一个cron来每小时运行一次:

Retrieve all article ids in databases
For each article
 Send a `zremrangebyscore "article.id:readers" -inf [current_timestamp]` to remove expired visitors_id

最后,要检索当前的读者数量,请运行ZCARD [article_id]:readers

注意

这种方法更好,因为它使用滑动窗口,因此在每个新的小时都不会有“0读取器”效果。然而,缺点是您需要遍历所有文章ID,这可能是一个问题。

方法#3:ZSET + ZCARD + ZSET作为索引+ cron

<强>解决方案

与方法#2相同,但是这个方法使用另一个zset articles:readers:zset,其中包含最近更新的所有zset密钥。

然后,您必须遍历此zset成员而不是所有文章ID。

注意

如果你这样走,请不要忘记从articles:readers:zset删除过期的成员!