2

我正在设计一种算法来计算一组页面上的唯一用户,基于 60 分钟的滑动比例

因此,它需要找到访问特定页面的唯一 IP(或令牌),并在过去 60 分钟内汇总这些命中

我需要它在规模上非常快(主要是写作,但阅读是一种奖励)。我们每页可以有 10,000 个用户乘以 1000 个页面。

我的研究指向我将 Redis 与 HyperLogLog 一起使用

我是来自 Memcache 背景的 Redis 新手。任何人都可以给我任何指示吗?

谢谢

4

2 回答 2

4

这样做的一种方法是为每个页面/页面集保留一个 HLL 密钥,并具有分钟的分辨率。例如,如果我们正在跟踪“index.html”并且当前时间戳为 0,则可以通过以下方式跟踪 ID 为“abc”的访问者:

PFADD index.html:0 abc

一旦一分钟过去了——即为简单起见,时间戳 1——一个访问者,如 'def' 将被添加到下一个键:

PFADD index.html:1 def

等等。要计算过去 60 分钟的唯一访问者数量,假设当前时间戳为 100,您需要调用该PFCOUNT命令并为其提供所有这 60 个键的名称,例如:

PFCOUNT index.html:100 index.html:99 ... index.html:41

注意:如果您希望逐出“旧”计数,请EXPIRE在每次调用PFADD.

于 2020-07-05T12:10:47.197 回答
1

您无法在单个HyperLogLog键中获得时间间隔。

排序集可能是一种选择;

  • 您将用户添加到排序集中,作为他们的进入日期作为分数,他们的用户 ID 作为值ZADD
  • 您可以使用ZCOUNT来获取该时间间隔内的唯一用户总数。例如,我使用小数字作为时间戳。
127.0.0.1:6379> ZADD activeusers:page:1 1 a1
(integer) 1
127.0.0.1:6379> ZADD activeusers:page:1 1 a2
(integer) 1
127.0.0.1:6379> ZADD activeusers:page:1 3 a5
(integer) 1
127.0.0.1:6379> ZADD activeusers:page:1 116 a7
(integer) 1
127.0.0.1:6379> ZCOUNT activeusers:page:1 60 inf
(integer) 1
127.0.0.1:6379> ZRANGEBYSCORE activeusers:page:1 60 inf
1) "a7"

当您使用ZCOUNT时,您将定义MIN为 (current time - (60*60)) 和MAXas inf,因此它需要介于 (now - 3600 秒) 和 (now) 之间。

这个缺点之一是,您需要通过使用手动从这些集合中删除旧数据ZREMRANGEBYSCORE

127.0.0.1:6379> ZREMRANGEBYSCORE activeusers:page:1 -inf 59
(integer) 3
127.0.0.1:6379> ZRANGEBYSCORE activeusers:page:1 -inf inf
1) "a7"
127.0.0.1:6379> ZRANGEBYSCORE activeusers:page:1 -inf inf WITHSCORES
1) "a7"
2) "116"
于 2020-07-05T12:16:30.180 回答