使用 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 的示例,听起来很像您正在做的事情。
计算唯一 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 由服务器自动处理并由客户端跟踪,无需更改您的应用程序。
我正在尝试为不同的客户计算每个页面或其他事件(如点击等)等的唯一身份访问者。我打算做的是分配一个基于 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 的示例,听起来很像您正在做的事情。
计算唯一 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 setpage-users
. This set (page-users
) can live in a namespace that stores SSD 上的数据。
如果此键存在:
- 增加该键的记录数。这将为每个页面提供瞬时唯一访问者计数。
一天结束时:
- 获取每个页面的计数,以及访问该页面的唯一用户列表。
- 从集合
page-users
中读取键为 - Assemble batch-read 与基于此用户 ID 列表的
users
集合。
<page ID : yyyymmdd>
的记录
优势
- 检查
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 由服务器自动处理并由客户端跟踪,无需更改您的应用程序。