Redis源码中hyperloglog结构的实现原理是啥
大数据领域的近似分析方法(一)基数估算问题基数估算(Cardinality Estimation),也称为 count-distinct problem,一直是大数据领域的重要问题之一。顾名思义,基数估算就是为了估算在一批数据中,它的不重复元素有多少个。
这个问题的应用场景十分广泛。例如:对于 Google 主页面而言,同一个账户可能会访问 Google 主页面多次。于是,在诸多的访问流水中,如何计算出 Google 主页面每天被多少个不同的账户访问过就是一个重要的问题。那么对于 Google 这种访问量巨大的网页而言,其实统计出有十亿 的访问量或者十亿零十万的访问量其实是没有太多的区别的,因此,在这种业务场景下,为了节省成本,其实可以只计算出一个大概的值,而没有必要计算出精准的值。
从数学上来说,基数估计这个问题的详细描述是:对于一个数据流
而言,它可能存在重复的元素,用
来表示这个数据流的不同元素的个数,i.e.
并且这个集合可以表示为
目标是:使用
这个量级的存储单位,可以得到
的估计值
其中
并且估计值
和实际值
的误差是可以控制的。
如果是想得到精确的基数,可以使用字典(dictionary)这一个数据结构。对于新来的元素,可以查看它是否属于这个字典;如果属于这个字典,则整体计数保持不变;如果不属于这个字典,则先把这个元素添加进字典,然后把整体计数增加一。当遍历了这个数据流之后,得到的整体计数就是这个数据流的基数了。
Naive Solution这种算法虽然精准度很高,但是使用的空间复杂度却很高。那么是否存在一些近似的方法,可以估算出数据流的基数呢?其实,在近几十年,不少的学者都提出了很多基数估算的方法,包括 LogLog,HyperLogLog,MinCount 等等。下面将会简要的介绍一下这些方法。
基数估计的部分算法HyperLogLog 的理论介绍HyperLogLog 是大数据基数统计中的常见方法,无论是 Redis,Spark 还是 Flink 都提供了这个功能,其目的就是在一定的误差范围内,用最小的空间复杂度来估算一个数据流的基数。
Spark 的 LogoHyperLogLog 算法简要思路是通过一个 hash 函数把数据流
映射到
也就是说用二进制来表示数据流中的元素。每一个数据流中的元素
推荐阅读
- microsoft redistributable为啥不做成一个带可选项的程序
- 网站完整源码能有途径获取吗
- cygwin下源码编译openssl出错
- redis中的hset怎样快速地找到最大key或最大value,有办法快速地知道一个hset中key的个数 或 value的个数吗
- 怎样借助 redis 进行内容的排序,并将关注的 feed 流推送进来,聚合在一起,显示出来
- 有关JDK源码中一些元素类型在方法实现方面的效率问题请大牛们指点迷津一下,谢谢!?
- wordpress首页文章摘要字数设置具体源码在文中!求大神!
- 开发一个网站的价格,做一个网站要多少钱,需要源码的呢
- 写一个类,让toString()输出这个类的源码
- 如果让一个程序随机的修改自己源码无限制的编译且复制自身,是否有一日会出现一个完善的人工智能
