Hyperloglog

发布于 2017-12-12 23:24:12

Redis 里有 HyperLogLog 数据结构,一直看不懂是什么意思,其实原理很简单。

在理想状态下,将一堆数据hash至[0,1],如果是随机均匀分布的话,每两点距离相等,测算出这个距离,那么 1/间距 就是这堆数据的基数,也就是数据的个数。

然而这个数据需要修正,太小或太大都是通过一个log函数来得到新的估计值。

计算过程:

  1. hash(Jekins Hash)成32位的值
  2. 初始化具有容量m = 2 ^ b的登记表
  3. hash 值的低 b 位被用于确定在表中位置,即 register index
  4. hash 值剩余位数的低位二进制0的个数+1作为 regiter value
  5. 当 register value 大于当前值的时候,替换掉原始值
  6. 使用 distinct value (DV) 算法计算基数并做调整。

这里有一个模拟页面,动态模拟这个估算过程。

原始信息通过hash函数变小之后,在加上是存储到每个“桶”里,使得存储空间变得很小。

在 Redis 中每个键占用的内容都是 12K,理论存储近似接近 2^64 个值,不管存储的内容是什么。 这是一个基于基数估计的算法,只能比较准确的估算出基数,可以使用少量固定的内存去存储并识别集合中的唯一元素。但是这个估算的基数并不一定准确,是一个带有 0.81% 标准错误(standard error)的近似值。 也正是因为只有 12K 的存储空间,所以,它并不实际存储数据的内容。

References

comments powered by Disqus