【转载】布隆过滤器参数设置

原文地址:布隆过滤器设置合适指标_布隆过滤器100万数据需要多少m-CSDN博客

 

布隆过滤器用于快速检测不存在数据,主要用位数组的结构来存储。其中为了保证布隆过滤器有适当的正确率通常会设置几个参数。

设:

k = hash函数个数,用于将一个数据通过不同hash函数计算为不同值,如“test” hash1-> 10,hash2-> 91, hash3->88等等,其中hash值即为位数组下标。如上面计算的三个值则位数组上坐标为10、91、88的位置上会被标记为1,其他位置还是0。

n = 数据量大小。如:现有一个100万文件的文件夹,我手中有一个文件不知道这个文件夹中是否有这个文件,如果没有就放进去,有的话我再另外处理。此时n则是100万

m = 位数组长度。如上面经过hash计算的值是小于一个最大值的,这个最大值则是这个位数组的长度。

p = 布隆过滤器正确率。hash计算的值位数是有限的,当数据量大了之后必然存在多个值重复交叉的问题,例如有另外两个数据三个hash函数算出的值分别是(11,10,88),(91,54,10),那如果这时再检测并没有存入的“test”它的hash值为(10,91,88)在位数组中是存在的。这时就会误报“test”已存在。那么这个误报率就是p。这里也可以看出布隆过滤器并不适合检测数据一定存在,而适合检测数据一定不存在。

使用布隆过滤器我们自然想要误报率p不能太高,当然长度m也不能太大不然还不如直接用其他更准确的数据结构。

那么这些参数的关系是怎样的呢。这里直接给出公式:

k=−lnp / ln2m=kn / ln2

可以看出hash函数个数只与精确度有关,而m与k值和数据量有关。

显然k值我们只能取整数,那么对应的p值为多少呢,这里我给出几个常见值对应表,

其中k/ln2用系数r表示即m=rn

k      p       r
1       0.5      1.442695041
2       0.25      2.885390082
3       0.125      4.328085123
4       0.0625     5.770780164
5       0.03125     7.213475204
6       0.015625     8.656170245
7       0.0078125     10.09886529
8       0.00390625     11.54156033
9       0.001953125     12.98425537
10       0.000976563     14.42695041
我们可以看到当k取5时的误判率已经小于5%,此时的系数约等于7。也就是说,如果数据量为100万,那么位数组长度需要700万才能保证使用5个hash函数时误判率小于5%。700万位,约等于875kb。如果一个文件只有1k大小,总大小也将近1G了。通过布隆过滤器,只需要875k的内存大小便能快速判断某个文件是否在这个文件夹中,且准确率高达96.8%。

布隆过滤器在大量数据判断是否存在的场景非常有用,速度快,占用内存少。

当然布隆过滤器最耗时可能在hash函数中。此时选择的hash函数也要考虑使用性能较高的hash函数才能使整体效率较高。当然hash函数的散列均匀度也影响误判概率。此文中的公式是默认所有hash函数计算的值是绝对均匀的。

说了这么多废话,你肯定会问:能不能给力点啊老师!talk is cheap,show me the code.

好了,google.guava已经给你实现好了。BloomFilter,用静态方法create(int parm1,double param2)进行构建。第一个参数是你准备填充的数据总量,即文中的n。第二个参数是失败率,如你期望失败率为5%,则参数传0.05;当然,这是在java语境中的对象过滤。所以,理论上你把失败率设置为很低也不会太占用内存,比如0.00000000001。当然前提是你的总量不会太大。不过,第一个参数也限定了是个int而不是long。虽然组合起来可能会让布隆过滤器占用内存很大。但,一般的应用,你的失败率只要不设置的过分离谱,谁在乎呢。

posted @ 2024-03-18 22:45  r1-12king  阅读(15)  评论(0编辑  收藏  举报