使用 Redis 或 Aerospike 计算唯一身份访问者

Count unique visitors with Redis or Aerospike

我正在尝试为不同的客户计算每个页面或其他事件(如点击等)等的唯一身份访问者。我打算做的是分配一个基于 cookie 的唯一 GUID,然后为每个事件调用 GUID 的 SADD。 redis 密钥将是 SET_[ EVENTID ]

如果我只想知道用户数,我可能会使用 PFADD,但我的应用还需要知道谁是唯一用户

但问题是,如果有太多的事件或太多的用户,那么 SADD 最终会在内存中留下大量的用户 ID 我们预计每小时 1000k+ 用户事件,在所有客户端中,事件数量也将是 100+

我想发表意见是 redis 是正确的存储选择。由于请求数量庞大

,任何传统的 RDBMS 方法都行不通

我不确定是否有任何其他存储可以提供像 Aerospike 这样的帮助

在 Redis 中对此进行建模的另一种方法是使用 Bitmaps 而不是使用集合。在您的情况下,维护 GUID 和表示位数组中索引的整数之间的映射。您可能需要考虑为每个事件使用存储桶,以避免因指标稀疏而造成的浪费。

几个 Redis-backed 分析库正在使用这种方法,例如参见 [​​=11=]。

Hyperloglog 和 Redis

听起来您可能想要的是 HyperLogLog。它是一种概率数据结构,允许您权衡准确性以支持恒定大小的数据结构。好的是 innacuracy 受数据结构大小的限制和决定。使用 1.5kB 的内存可以让您获得与正确答案相差约 2% 的唯一计数。每个计数器使用更多数据,获得更高的准确性。

此外,此功能内置于 Redis 中。

Hyperloglog 维基页面: https://en.wikipedia.org/wiki/HyperLogLog

相关Redis博客post: http://antirez.com/news/75

HyperLogLog 和 VoltDB

如果您对具有比 Redis 更好的 HA 支持的更传统的 RDBMS 模型感兴趣,请查看 VoltDB。它支持盒子上的极端吞吐量,也支持本地集群。此外,它有丰富的 SQL 支持来完成 Redis 所做的许多事情(甚至更多)。它还在 SQL 中内置了 hyperloglog 支持。它还有一个计算唯一 ID 的示例,听起来很像您正在做的事情。

http://voltdb.com

计算唯一 ID 的示例: https://github.com/VoltDB/voltdb/tree/master/examples/uniquedevices

RTB, where Aerospike is used heavily, frequency capping 中是 Demand-Side 平台 (DSP) 的常见用例。用户看到特定广告或来自特定活动的广告的次数有上限。同时,跟踪总展示次数以及剩余预算。这些计数器通常具有较短的 TTL。

解决方案

您可以使用复合键 <page ID : user ID : yyyymmdd> 作为特定用户是否访问过页面的标志,TTL 为 24 小时。这将存在于 in-memory、data-in-index namespace 的集合 page-visit 中。

如果没有这样的键:

  • 在集合 page-visit 中使用此键创建一条新记录,初始值为 1。
  • list-append the user ID to a key <page ID : yyyymmdd> in the set page-users. This set (page-users) can live in a namespace that stores SSD 上的数据。

如果此键存在:

  • 增加该键的记录数。这将为每个页面提供瞬时唯一访问者计数。

一天结束时:

  • 获取每个页面的计数,以及访问该页面的唯一用户列表。
  • 从集合page-users
  • 中读取键为<page ID : yyyymmdd>的记录
  • Assemble batch-read 与基于此用户 ID 列表的 users 集合。

优势

  • 检查 page-visit 标志的延迟非常低。它使用非常少的内存,因为 data-in-index namespaces 没有额外的 space 超过 Aerospike 中每个对象的 64B 元数据成本。例如,10M 用户 * 64B * replication-factor 2 = 1.2GB DRAM.
  • 唯一用户列表 per-page 存储在 SSD 上,成本 per-GB 比仅 in-memory 的数据库(如 Redis)低得多。您只需为 in-memory primary index 中的元数据条目支付 64B per-object。 list-append 操作非常高效,因为您只发送要附加到 page-users 记录的最新用户 ID。仅当页面上出现新的唯一用户时才使用此操作(由 page-visit 标志保护)。
  • 所有这些记录都有 24 小时 TTL,因此您可以让它们过期。
  • Aerospike 是一个分布式 key-value 数据库,它可以垂直扩展以使用服务器上的所有核心,并且水平扩展时您的应用程序不需要在新节点加入时进行分片。 data distribution 由服务器自动处理并由客户端跟踪,无需更改您的应用程序。