PFCOUNT

语法
PFCOUNT key [key ...]
可用时间
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 在需要时会自动从稀疏表示切换到密集表示。

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

两种表示都以 16 字节的标题为前缀,其中包含魔术值、编码/版本字段以及存储的已计算基数估计值,以小端格式存储(如果自计算基数以来 HyperLogLog 已更新,则最高有效位为 1,表示估计值无效)。

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

表示形式对处理器字大小和字节序是中性的,因此 32 位和 64 位处理器、大端或小端使用相同的表示形式。

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

RESP2 响应

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

RESP3 响应

整数响应:通过 PFADD 观察到的唯一元素的近似数量
RATE THIS PAGE
Back to top ↑