redis的HyperLogLog与布隆过滤器

Posted codingjav

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis的HyperLogLog与布隆过滤器相关的知识,希望对你有一定的参考价值。

HyperLogLog与布隆过滤器都是针对大数据统计存储应用场景下的知名算法。

HyperLogLog是在大数据量的情况下关于数据基数的空间复杂优化实现,而布隆过滤是在大数据量情况下关于检索一个元素是否存在于一个集合中的空间复杂优化后的实现。

在传统的数据量较低的应用服务中,我们实现数据基数和数据是否存在分析的功能,通常是简单把数据存储下来,直接count一下就是基数了,而直接检索一个元素是否存在集合中也是非常简单。

但是随着数据量的急剧增大,传统方式已经很难达到工程上的诉求了。海量数据无论是在存储还是在查询方面都存在巨大的挑战,无论是使用位存储还是树结构存储来优化,都没有办法达到大数据时代要求。  于是HyperLogLog与布隆过滤器这两个算法就很好的派上用场。他们的使用可以极大的节约存储空间,作为代价,则是牺牲了一个小概率的准确性,这可以很好的达到工程上的需求,对于那些要求准确度没那么高,但数据量巨大的需求是非常合适的。

HyperLogLog原理

最直白的解释是,给定一个集合 S,对集合中的每一个元素,我们做一个哈希,假设生成一个 16 位的比特串,从所有生成的比特串中挑选出前面连续 0 次数最多的比特串,假设为 0000000011010110,连续 0 的次数为 8,因此我们可以估计该集合 S 的基数为 2^9。当然单独用这样的单一估计偶然性较大,导致误差较大,因此在实际的 HyperLogLog 算法中,采取分桶平均原理了来消除误差。(这段话引用了 HyperLogLog 原理  中的描述,还有一些细节实现 感兴趣可阅读 https://blockchain.iethpay.com/hyperloglog-theory.html

特点:实现牺牲了一定的准确度(在一些场景下是可以忽略的),但却实现了空间复杂度上的极大的压缩,可以说是性价比很高的。

虽然基数不完全准确,但是可以符合,随着数量的递增,基数也是递增的。

布隆过滤器原理

布隆过滤器(Bloom Filter)的核心实现是一个超大的位数组和几个哈希函数。假设位数组的长度为m,哈希函数的个数为k,以上图为例,具体的操作流程:假设集合里面有3个元素{x, y, z},哈希函数的个数为3。首先将位数组进行初始化,将里面每个位都设置为0。对于集合里面的每一个元素,将元素依次通过3个哈希函数进行映射,每次映射都会产生一个哈希值,这个值对应位数组上面的一个点,然后将位数组对应的位置标记为1。查询W元素是否存在集合中的时候,同样的方法将W通过哈希映射到位数组上的3个点。如果3个点的其中有一个点不为1,则可以判断该元素一定不存在集合中。反之,如果3个点都为1,则该元素可能存在集合中。注意:此处不能判断该元素是否一定存在集合中,可能存在一定的误判率。可以从图中可以看到:假设某个元素通过映射对应下标为4,5,6这3个点。虽然这3个点都为1,但是很明显这3个点是不同元素经过哈希得到的位置,因此这种情况说明元素虽然不在集合中,也可能对应的都是1,这是误判率存在的原因。(这段话与图片引用于 布隆过滤器(Bloom Filter)的原理和实现  中的描述,还有一些细节实现 感兴趣可阅读 https://www.cnblogs.com/cpselvis/p/6265825.html

特点:巧妙的使用hash算法和bitmap位存储的方式,极大的节约了空间。

       由于主要用的是hash算法的特点,所有满足和hash算法相同的规则:当过滤器返回 true时(表示很有可能该值是存在的),有一定概率是误判的,即可能不存在;当过滤器返回false时(表示确定不存在),是可以完全相信的。

       我们换个数据的角度来看规则:当数据添加到布隆过滤器中时,对该数据的查询一定会返回true;当数据没有插入过滤器时,对该数据的查询大部分情况返回false,但有小概率返回true,也就是误判。

   我们知道它最终满足的规则和hash的规则是一致的,只是组合了多个hash,使用了bitmap来存储,大大优化了存储的空间和判断的效率。

redis中的HyperLogLog

在redis中对HyperLogLog 的支持早在2.8.9的时候就有了。它的操作非常简单

  • PFADD  给HyperLogLog添加值
  • PFCOUNT 获取基数
  • PFMERGE 合并两个HyperLogLog数据(完美合并,分别添加和统一添加的结果是一致的)

redis中的布隆过滤器

 在redis中的布隆过滤器的支持是在redis4.0后支持插件的情况下,通过插件的方式实现的 ,redis的布隆过滤器插件地址:https://github.com/RedisLabsModules/rebloom

它的操作也很简单,以下为几个主要命令,其它命令请参考文档 https://github.com/RedisLabsModules/rebloom/blob/master/docs/Bloom_Commands.md

参考文章

布隆过滤器(Bloom Filter)的原理和实现

https://github.com/RedisLabsModules/rebloom/blob/master/docs/Bloom_Commands.md

Redis-HyperLogLog

HyperLogLog算法原理及其redis使用

以上是关于redis的HyperLogLog与布隆过滤器的主要内容,如果未能解决你的问题,请参考以下文章

Redis——亿级数据过滤和布隆过滤器

Redis亿级数据过滤和布隆过滤器

Redis之亿级数据过滤和布隆过滤器

深入详解Redis布隆过滤器

Redis 技术内幕——布隆过滤器

应用 5:层峦叠嶂 —— redis布隆过滤器