PFCOUNT
PFCOUNT key [key ...]
- 从以下位置开始可用:
- 2.8.9
- 时间复杂度:
- O(1) 使用单个 key 调用时,平均常量时间非常小。O(N),其中 N 是键的数量,当使用多个键调用时,常数要大得多。
- ACL 类别:
-
@read
,@hyperloglog
,@slow
,
当使用单个键调用时,返回存储在指定变量处的 HyperLogLog 数据结构计算的近似基数,如果变量不存在,则为 0。
当使用多个键调用时,通过将存储在所提供键处的 HyperLogLogs 内部合并到临时 HyperLogLog 中,返回所传递的 HyperLogLog 并集的近似基数。
HyperLogLog 数据结构可用于仅使用少量恒定内存对集合中的唯一元素进行计数,特别是每个 HyperLogLog 的 12k 字节(加上键本身的几个字节)。
返回的观测集的基数并不精确,而是近似为 0.81% 的标准误差。
例如,为了计算一天内执行的所有唯一搜索查询的计数,程序需要调用PFADD
每次处理查询时。可以使用以下方法检索唯一查询的估计数量PFCOUNT
随时。
注意:作为调用此函数的副作用,HyperLogLog 可能会被修改,因为最后 8 个字节编码了最新计算的基数
用于缓存目的。所以PFCOUNT
从技术上讲是一个写入命令。
例子
性能
什么时候PFCOUNT
使用单个 key 调用,即使
理论上,处理密集 HyperLogLog 的恒定时间是很高的。这是
可能,因为PFCOUNT
使用 caching 来记住 cardinality
以前计算的,那很少改变,因为大多数PFADD
作将
不更新任何寄存器。每秒可以进行数百次作。
什么时候PFCOUNT
使用多个键调用,则
HyperLogLogs 执行,这很慢,而且联合的基数
无法缓存,因此当与多个 key 一起使用时PFCOUNT
可能需要一段时间
毫秒的数量级,不应被滥用。
用户应记住,单键和多键执行 此命令在语义上不同,并且具有不同的性能。
HyperLogLog 表示
Redis HyperLogLog 使用双重表示表示:稀疏表示形式适用于计算少量元素的 HLL(导致少量寄存器设置为非零值),而密集表示形式适用于更高的基数。Redis 会在需要时自动从 sparse 表示切换到 dense 表示。
稀疏表示使用经过优化的 run-length encoding 来有效地存储大量设置为 0 的 registers。密集表示形式是一个 12288 字节的 Redis 字符串,用于存储 16384 个 6 位计数器。对 double 表示的需求来自这样一个事实,即使用 12k (这是密集表示内存要求)来为较小的基数编码几个 registers 是非常不理想的。
两种表示形式都以 16 字节的标头为前缀,其中包括一个魔术、一个 encoding / version 字段和计算的缓存基数估计,以 little endian 格式存储(如果估计无效,则最高有效位为 1,因为 HyperLogLog 在计算基数后已更新)。
HyperLogLog 是一个 Redis 字符串,可以使用GET
并使用SET
.叫PFADD
,PFCOUNT
或PFMERGE
HyperLogLog 损坏的命令从来都不是问题,它可能会返回随机值,但不会影响服务器的稳定性。大多数情况下,在损坏稀疏表示时,服务器会识别出损坏并返回错误。
从处理器字长和字节序的角度来看,这种表示形式是中性的,因此 32 位和 64 位处理器、大端或小端使用相同的表示形式。
有关 Redis HyperLogLog 实现的更多详细信息,请参阅此博客文章。在hyperloglog.c
文件也易于阅读和理解,并且包括用于稀疏和密集表示的确切编码的完整规范。
RESP2 回复
Integer reply:通过PFADD
.RESP3 回复
Integer reply:通过PFADD