Redis 的 HyperLogLog 数据结构实现了一种基于概率的基数估算算法,用于在占用极小内存的情况下估算一个集合中不重复元素(唯一值)的数量。以下是 HyperLogLog 算法的基本原理:
-
哈希函数:
- HyperLogLog 使用一个强散列函数将输入的元素映射为固定长度的二进制串。
-
位前导零统计:
- 对每个元素经过哈希后的二进制串,统计从最高位开始连续零的个数(即前导零个数)。这个值反映了元素哈希值的稀有程度,间接表示了元素的独特性。
-
存储与计数:
- Redis 中的 HyperLogLog 结构内部维护了一个大小固定的桶数组,默认大小为 2^14 = 16384 个桶。
- 每个桶用于存储对应的元素哈希值所观察到的最大前导零个数。
- 当添加新的元素时,它会被哈希并找到对应的桶来更新该桶中的最大前导零计数值。
-
基数估算:
- 利用统计的所有桶中最长的前导零序列,通过预定义的公式计算出一个近似的基数(唯一元素数量),这个估算值通常会非常接近实际基数,但不是精确值。
- 标准误差大约是 0.81%,这意味着对于大量数据,HyperLogLog 能够以相对较小的误差估计基数。
-
空间效率:
- 即使可以处理多达 2^64 (18亿左右)个不同的元素,Redis 中单个 HyperLogLog 键只需要大约 12KB 的固定内存空间。
- 在初始阶段或基数较小的时候,HyperLogLog 使用稀疏存储模式,随着基数增加,当满足一定条件后会转换为稠