大数据量的存储、筛选、重排等背景下产生的优秀算法。
在大数据量下,应用程序,会出现很多空间,时间的问题。常用的思想就是:将每条数据通过一定的算法转变成占存更小的ID(指纹),通过对指纹的存储和计算来对整个数据量级的减少。(合理的运用容器,指纹之间也可以通过分段的方式共用相同的存储块)
布隆过滤器的的着重点是过滤,不关心具体的业务内容。适用场景:计算一个url在一个url集(大数据量)中是否存在爬虫访问记录。
步骤解析
“通过一定的算法转变成占存更小的ID(指纹)”:Hash算法可以支持(用Hash就要容忍Hash的弊端:Hash冲突,幸运的是一般用到布隆过滤器的场景都需要那么精确)
“指纹的存储和计算来对整个数据量级的减少”:指纹映射到一个大的按位存储的空间中(指纹之间也可以通过分段的方式共用相同的存储块)
优点:空间和时间效率都很高。 缺点:随着存入的元素数量增加,误算率(HASH)随之增加。
具体实现
“Hash算法可以支持”,但一个hash函数的冲突率会很大,可以原值通过N个Hash算法得到N个数字,将N个数字对应在“按位存储的空间中”(bitMap,int[])下标的值变为1.具体实现看开发者。
这样就完成了数据的“转变存储”,判断一个值存不存在,通过对应算法算出N个数字,去bitMap中看每个下标对应的值是否都是1即可。
当然有误判率。
注意点
““按位存储的空间中”(bitMap,int[])” 中位数如何限定?
过小的布隆过滤器很快所有的 bit 位均为 1。布隆过滤器的长度会直接影响误报率,布隆过滤器越长其误报率越小。
“N个Hash算法”,N怎么取?
个数越多则布隆过滤器 bit 位置位 1 的速度越快,且布隆过滤器的效率越低;但是如果太少的话,那我们的误报率会变高。
假设 Hash 函数以等概率条件选择并设置 Bit Array 中的某一位,m 是该位数组的大小,k 是 Hash 函数的个数。
而对于给定的False Positives概率 p,如何选择最优的位数组大小 m 呢,
上式表明,位数组的大小最好与插入元素的个数成线性关系,对于给定的 m,n,k,假正例概率最大为:
摘自:https://www.cnblogs.com/bonelee/p/6215176.html
java代码j简单示例
public class BloomFilter<T> {
//bit容器
private byte[] bitMap;
//容器长度
private int BIT_MAP_LENGTH;
//hash个数
private int HASH_NUM;
public BloomFilter(int BIT_MAP_LENGTH, int HASH_NUM) {
this.bitMap = new byte[BIT_MAP_LENGTH];
this.BIT_MAP_LENGTH = BIT_MAP_LENGTH;
this.HASH_NUM = HASH_NUM;
}
private int[] getHash(T value) {
int[] result = new int[HASH_NUM];
Stream.iterate(0, i -> i + 1).limit(HASH_NUM).forEach(i -> result[i] = (value.toString() + i).hashCode() % BIT_MAP_LENGTH);
return result;
}
public boolean isContain(T value) {
for (int hash : getHash(value)) {
if (bitMap[hash] != 1) {
return false;
}
}
return true;
}
public void add(T value) {
for (int hash : getHash(value)) {
bitMap[hash] = 1;
}
}
public static void main(String[] args) {
BloomFilter bloomFilter = new BloomFilter<String>(1024, 8);
Stream.iterate(1, i -> i + 1).limit(1024).forEach(i -> bloomFilter.add(i));
System.out.println(bloomFilter.isContain(1));
System.out.println(bloomFilter.isContain(10000000));
}
}
分布式系统中,可基于redis的bitMap作为容器来实现。原理一样。
布隆过滤器有很多致命软肋,有人推布谷鸟过滤器
https://zhuanlan.zhihu.com/p/68418134
主要还是看场景吧。