redis - 如何在 Redis 中存储唯一访问

标签 redis stackexchange.redis

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

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

有什么想法吗?

最佳答案

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

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

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

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

> PFADD cnt:page-name:20200917 {userID}

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

> PFCOUNT cnt:page-name:20200917

您可以通过为不同的时间间隔设置不同的 HLL 来更改唯一用户的粒度,例如 cnt:page-name:202009 表示 2020 年 9 月。

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

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

如果您对内部实现感到好奇,Antirez 的发布帖子非常适合阅读:http://antirez.com/news/75

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

关于redis - 如何在 Redis 中存储唯一访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63899091/

相关文章:

java - 如何在 Spring Redis 模板中禁用 z-operations

indexing - 原子添加/删除索引(集合)值到 Redis 中的哈希属性

使用 StackExchange.Redis 与 Redis 进行 SSL 连接

stackexchange.redis - 如何将 TextWriter 用作 Serilog 的源?

php - 如何在 laravel 中监听所有队列?

ruby-on-rails - 即使在 Resque 作业成功完成后,Redis 键也没有被删除

kubernetes - 具有大型数据集的 Redis 就绪探针

redis - 如何将 Redis 命令 'expire' 和 'sadd' 合并为一个命令?

redis - stackexchange.redis 通配符删除

redis - Redis 的 BGSAVE 命令等效的 StackExchange.Redis 方法名称是什么