Redis系列学习笔记7 HyperLogLog

HyperLogLog

使用常量空间估算大量元素的基数。

问题

记录网站每天获得的独立 IP 数量。

使用集合来储存每个访客的 IP ,通过集合性质(集合中的每个元素都各不相同)来得到多个独立 IP ,然后通过调用 SCARD 命令来得出独立 IP 的数量。

为了更好地解决像独立 IP 地址计算这种问题,Redis 在 2.8.9 版本添加了 HyperLogLog 结构。

HyperLogLog 介绍

HyperLogLog 可以接受多个元素作为输入,并给出输入元素的基数估算值:

  • 基数:集合中不同元素的数量。比如 {‘apple’, ‘banana’, ‘cherry’, ‘banana’, ‘apple’} 的基数就是 3 。
  • 估算值:算法给出的基数并不是精确的,可能会比实际稍微多一些或者稍微少一些,但会控制在合理的范围之内。

HyperLogLog 的优点是,即使输入元素的数量或者体积非常非常大,计算基数所需的空间总是固定的、并且是很小的。

在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以HyperLogLog 不能像集合那样,返回输入的各个元素。

将元素添加至 HyperLogLog

PFADD key element [element …]

将任意数量的元素添加到指定的 HyperLogLog 里面。

这个命令可能会对 HyperLogLog 进行修改,以便反映新的基数估算值,如果 HyperLogLog 的基数估算值在命令执行之后出现了变化, 那么命令返回 1 , 否则返回 0 。

PFCOUNT key [key …]

当只给定一个 HyperLogLog 时,命令返回给定 HyperLogLog 的基数估算值。

当给定多个 HyperLogLog 时,命令会先对给定的 HyperLogLog 进行并集计算,得出一个合并后的HyperLogLog ,然后返回这个合并 HyperLogLog 的基数估算值作为命令的结果(合并得出的HyperLogLog 不会被储存,使用之后就会被删掉)。

当命令作用于单个 HyperLogLog 时, 复杂度为 O(1) , 并且具有非常低的平均常数时间。

当命令作用于多个 HyperLogLog 时, 复杂度为 O(N) ,并且常数时间也比处理单个 HyperLogLog 时要大得多。

PFMERGE destkey sourcekey [sourcekey …]

将多个 HyperLogLog 合并为一个 HyperLogLog ,合并后的 HyperLogLog 的基数估算值是通过对所有给定 HyperLogLog 进行并集计算得出的。

唯一计数器

API 作用 实现原理
UniqueCounter(client, key) 指定客户端以及键名。
UniqueCounter.include(element) 将给定的元素计算在内。 PFADD
UniqueCounter.result() 返回计数器当前的值 PFCOUNT

你可能感兴趣的:(Redis)