PFADD key [element [element ...]]
自 2.8.9 起可用。
时间复杂度: O(1) 添加每个元素。
将所有元素参数添加到存储在指定为第一个参数的变量名称处的 HyperLogLog 数据结构中。
作为此命令的副作用,HyperLogLog 内部可能会更新,以反映对迄今为止添加的唯一项目数量(集合的基数)的不同估计。
如果 HyperLogLog 估计的近似基数在执行命令后发生变化,则 PFADD返回 1,否则返回 0。如果指定的键不存在,该命令会自动创建一个空的 HyperLogLog 结构(即指定长度和给定编码的 Redis 字符串)。
调用不带元素但仅变量名有效的命令,如果变量已存在则不执行任何操作,或者如果键不存在则仅创建数据结构(在后一种情况下返回 1) .
有关 HyperLogLog 数据结构的介绍,请查看PFCOUNT命令页面。
返回值
整数回复,具体来说:
- 如果至少 1 个 HyperLogLog 内部寄存器被更改,则为 1。否则为 0。
例子
redis> PFADD hll a b c d e f g
(integer) 1
redis> PFCOUNT hll
(integer) 7
redis>
PFCOUNT key [key ...]
自 2.8.9 起可用。
时间复杂度: O(1),当使用单个键调用时,平均常数时间非常小。O(N) 其中 N 是键的数量,当使用多个键调用时,常数时间要大得多。
当使用单个键调用时,返回由存储在指定变量中的 HyperLogLog 数据结构计算的近似基数,如果该变量不存在,则返回 0。
当使用多个键调用时,通过内部将存储在提供的键处的 HyperLogLogs 合并到临时 HyperLogLog 中,返回传递的 HyperLogLogs 联合的近似基数。
可以使用 HyperLogLog 数据结构来计算集合中的唯一元素,只需使用少量的常量内存,特别是每个 HyperLogLog 的 12k 字节(加上键本身的几个字节)。
观察集的返回基数并不精确,但以 0.81% 的标准误差近似。
例如,为了计算一天中执行的所有唯一搜索查询的计数,程序需要在每次处理查询时调用PFADD 。可以随时使用PFCOUNT检索估计的唯一查询数。
注意:作为调用此函数的副作用,HyperLogLog 可能会被修改,因为最后 8 个字节编码最新计算的基数以用于缓存目的。所以PFCOUNT在技术上是一个写命令。
返回值
整数回复,具体来说:
- 通过PFADD观察到的唯一元素的近似数量。
例子
redis> PFADD hll foo bar zap
(integer) 1
redis> PFADD hll zap zap zap
(integer) 0
redis> PFADD hll foo bar
(integer) 0
redis> PFCOUNT hll
(integer) 3
redis> PFADD some-other-hll 1 2 3
(integer) 1
redis> PFCOUNT hll some-other-hll
(integer) 6
redis>
表演
当使用单个键调用PFCOUNT时,即使理论上处理密集 HyperLogLog 的恒定时间很高,性能也很出色。这是可能的,因为PFCOUNT使用缓存来记住先前计算的基数,因为大多数PFADD操作不会更新任何寄存器,所以很少更改。每秒可以进行数百次操作。
当PFCOUNT被多个key调用时,会进行HyperLogLogs的on-the-fly合并,速度很慢,而且union的基数不能被缓存,所以当PFCOUNT与多个key一起使用时,可能会在毫秒的数量级,不应滥用。
用户应该记住,这个命令的单键和多键执行在语义上是不同的,并且具有不同的性能。
HyperLogLog 表示
Redis HyperLogLogs 使用双重表示表示:适用于 HLL 计数少量元素(导致少数寄存器设置为非零值)的稀疏表示,以及适用于更高基数的密集表示。Redis 在需要时会自动从稀疏表示切换到密集表示。
稀疏表示使用经过优化的游程编码来有效地存储大量设置为零的寄存器。密集表示是一个 12288 字节的 Redis 字符串,用于存储 16384 个 6 位计数器。对双重表示的需求来自这样一个事实,即使用 12k(这是密集表示内存要求)仅对较小基数的几个寄存器进行编码是非常次优的。
两种表示形式都以 16 字节标头为前缀,其中包括魔术、编码/版本字段和计算的缓存基数估计,以小端格式存储(如果自 HyperLogLog 更新后估计无效,则最高有效位为 1因为计算了基数)。
HyperLogLog 是一个 Redis 字符串,可以使用GET检索并使用SET恢复。使用损坏的 HyperLogLog调用PFADD、PFCOUNT或PFMERGE命令从来都不是问题,它可能会返回随机值但不会影响服务器的稳定性。大多数情况下,当损坏稀疏表示时,服务器会识别损坏并返回错误。
从处理器字长和字节序的角度来看,该表示是中性的,因此 32 位和 64 位处理器使用相同的表示,无论是大端还是小端。
有关 Redis HyperLogLog 实现的更多详细信息,请参阅此博客文章。文件中实现的源代码hyperloglog.c也易于阅读和理解,并且包含用于稀疏和密集表示的精确编码的完整规范。
PFDEBUG
自 2.8.9 起可用。
时间复杂度:不适用
PFDEBUG命令是一个内部命令。它旨在用于开发和测试 Redis。
PFMERGE destkey sourcekey [sourcekey ...]
自 2.8.9 起可用。
时间复杂度: O(N) 合并 N 个 HyperLogLogs,但常数时间很高。
将多个 HyperLogLog 值合并为一个唯一值,该值将近似于观察到的源 HyperLogLog 结构集的并集的基数。
计算的合并 HyperLogLog 设置为目标变量,如果不存在则创建该变量(默认为空 HyperLogLog)。
如果目标变量存在,则将其视为源集之一,其基数将包含在计算的 HyperLogLog 的基数中。
返回值
简单字符串回复:命令只是返回OK。
例子
redis> PFADD hll1 foo bar zap a
(integer) 1
redis> PFADD hll2 a b c foo
(integer) 1
redis> PFMERGE hll3 hll1 hll2
"OK"
redis> PFCOUNT hll3
(integer) 6
redis>
PFSELFTEST
自 2.8.9 起可用。
时间复杂度:不适用
PFSELFTEST命令是一个内部命令。它旨在用于开发和测试 Redis。