PFCOUNT

语法
PFCOUNT key [key ...]
可用版本
Redis 开源版 2.8.9
时间复杂度
当使用单个键调用时,时间复杂度为 O(1),平均常数时间非常小。当使用多个键调用时,时间复杂度为 O(N),其中 N 是键的数量,且常数时间要大得多。
ACL 分类
@read, @hyperloglog, @slow,

当使用单个键调用时,返回存储在指定变量中的 HyperLogLog 数据结构计算出的近似基数,如果变量不存在,则返回 0。

当使用多个键调用时,通过将提供的键存储的 HyperLogLogs 内部合并到一个临时 HyperLogLog 中,返回传递的 HyperLogLogs 并集的近似基数。

HyperLogLog 数据结构可用于使用少量固定内存来计算集合中的**唯一**元素,具体来说,每个 HyperLogLog 需要 12k 字节(加上键本身的几个字节)。

返回的观测集合的基数并非精确值,而是标准误差为 0.81% 的近似值。

例如,为了统计一天内所有唯一的搜索查询数量,程序需要在处理每次查询时调用 PFADD。随时可以通过 PFCOUNT 获取唯一的查询估计数量。

注意:调用此函数的一个副作用是 HyperLogLog 可能会被修改,因为最后 8 个字节编码了用于缓存的最新计算基数。因此,从技术上讲,PFCOUNT 是一个写入命令。

示例

PFADD hll foo bar zap PFADD hll zap zap zap PFADD hll foo bar PFCOUNT hll PFADD some-other-hll 1 2 3 PFCOUNT hll some-other-hll

性能

当使用单个键调用 PFCOUNT 时,性能非常出色,即使理论上处理密集型 HyperLogLog 的常数时间很高。这是因为 PFCOUNT 使用缓存来记住之前计算的基数,该基数很少变化,因为大多数 PFADD 操作不会更新任何寄存器。每秒可以处理数百次操作。

当使用多个键调用 PFCOUNT 时,会进行 HyperLogLogs 的即时合并,这会很慢,此外,并集的基数无法缓存,因此当与多个键一起使用时,PFCOUNT 可能需要毫秒量级的时间,不应滥用。

用户应注意,此命令的单键和多键执行在语义上是不同的,并且具有不同的性能。

HyperLogLog 表示形式

Redis HyperLogLogs 使用双重表示形式:稀疏表示形式适用于计算少量元素(导致设置为非零值的寄存器数量很少)的 HLL,密集表示形式适用于较高的基数。Redis 在需要时会自动从稀疏表示形式切换到密集表示形式。

稀疏表示形式使用行程长度编码,经过优化可有效地存储大量设置为零的寄存器。密集表示形式是一个 12288 字节的 Redis 字符串,用于存储 16384 个 6 位计数器。需要双重表示形式是因为对于较小的基数,使用 12k(密集表示形式的内存需求)来编码少量寄存器效率极低。

两种表示形式都带有 16 字节的头部前缀,其中包括一个魔数、一个编码/版本字段以及计算出的缓存基数估计值,以小端格式存储(如果自上次计算基数以来 HyperLogLog 已更新,则最高有效位为 1,表示估计值无效)。

HyperLogLog 作为 Redis 字符串,可以使用 GET 获取,使用 SET 恢复。使用损坏的 HyperLogLog 调用 PFADDPFCOUNTPFMERGE 命令永远不是问题,它可能返回随机值,但不会影响服务器的稳定性。大多数情况下,当稀疏表示形式损坏时,服务器会识别损坏并返回错误。

从处理器字长和字节序的角度来看,该表示形式是中立的,因此 32 位和 64 位处理器、大端序或小端序都使用相同的表示形式。

有关 Redis HyperLogLog 实现的更多详细信息,请参阅这篇博客文章hyperloglog.c 文件中的实现源代码也易于阅读和理解,并包含稀疏和密集表示形式所用精确编码的完整规范。

RESP2 回复

整数回复:通过 PFADD 观察到的唯一元素的近似数量。

RESP3 回复

整数回复:通过 PFADD 观察到的唯一元素的近似数量
评价此页面
返回顶部 ↑