如何在 Redis 中存储唯一访问次数

Mad*_*die 4 redis stackexchange.redis

我想知道有多少人访问了每个博客页面。为此,我在博客表 (MS SQL DB) 中有一列来记录总访问次数。但我也希望这次访问尽可能独特。所以我将用户的唯一Id和博客Id保存在Redis缓存中,每次用户访问一个页面时,我都会检查她之前是否访问过该页面,如果没有,我会增加总访问次数。

我的问题是,存储此类数据的最佳方式是什么?目前,我创建一个像这样的键“project-visit-{blogId}-{userId}”并使用 StringSetAsync 和 StringGetAsync。但我不知道这个方法是否有效。

有任何想法吗?

Ele*_*ska 6

如果您可以牺牲一些精度,HyperLogLog (HLL) 概率数据结构是计算唯一访问次数的绝佳解决方案,因为:

  • 它只使用 12K 内存,并且这些内存是固定的 - 它们不会随着唯一访问次数的增加而增长
  • 您不需要存储用户数据,这使您的服务更加注重隐私

HyperLogLog 算法确实很聪明,但您无需了解其内部工作原理即可使用它,几年前 Redis 将其添加为数据结构。因此,作为用户,您需要知道的是,使用 HyperLogLogs,您可以对 12K 固定内存空间中的唯一元素(访问)进行计数,误差范围为 0.81%

假设您想要记录每天的独立访问次数;您每天必须有一个 HyperLogLog,其名称类似于cnt:page-name:20200917每次用户访问页面时,您都会将它们添加到 HLL:

> PFADD cnt:page-name:20200917 {userID}
Run Code Online (Sandbox Code Playgroud)

如果多次添加同一用户,他们仍然只会被计数一次。要获取您运行的计数:

> PFCOUNT cnt:page-name:20200917
Run Code Online (Sandbox Code Playgroud)

cnt:page-name:202009您可以通过在不同时间间隔(例如2020 年 9 月)使用不同的 HLL 来更改唯一用户的粒度。

这个快速解释器很好地阐述了它:https://www.youtube.com/watch ?v=UAL2dxl1fsE

这篇博文也可能有帮助:https ://redislabs.com/redis-best-practices/counting/hyperloglog/

如果您对内部实现感到好奇,Antirez 的发布帖子值得一读: http: //antirez.com/news/75

注意:请注意,使用此解决方案,您会丢失访问该页面的用户的信息,您只有计数