
布隆过滤器是一种概率型数据结构,像一位聪明的「安检员」:
示例:假设有1000万用户ID,用布隆过滤器只需约2.4MB内存(传统哈希表需约40MB),但可能有1%的误判率。
import java.util.BitSet;
import java.util.Random;
public class BloomFilter {
private BitSet bitArray;
private int size;
private int[] hashSeeds; // 哈希函数种子
private int hashCount;
// 初始化:n=预期元素数量, p=可接受误判率
public BloomFilter(int n, double p) {
this.size = optimalSize(n, p);
this.hashCount = optimalHashCount(n, size);
this.bitArray = new BitSet(size);
this.hashSeeds = new int[hashCount];
Random rand = new Random();
for (int i = 0; i < hashCount; i++) {
hashSeeds[i] = rand.nextInt();
}
}
// 添加元素
public void add(String element) {
for (int seed : hashSeeds) {
int hash = (element.hashCode() ^ seed) % size;
bitArray.set(Math.abs(hash), true);
}
}
// 检查存在性
public boolean contains(String element) {
for (int seed : hashSeeds) {
int hash = (element.hashCode() ^ seed) % size;
if (!bitArray.get(Math.abs(hash))) return false;
}
return true; // 可能存在(有误判概率)
}
// 计算最优位数组大小(公式:m = -n*ln(p)/(ln2)^2)
private int optimalSize(int n, double p) {
return (int) (-n * Math.log(p) / (Math.pow(Math.log(2), 2)));
}
// 计算最优哈希函数数量(公式:k = m/n * ln2)
private int optimalHashCount(int n, int m) {
return Math.max(1, (int) (m / n * Math.log(2)));
}
public static void main(String[] args) {
BloomFilter filter = new BloomFilter(1_000_000, 0.01);
filter.add("user123");
System.out.println(filter.contains("user123")); // true
System.out.println(filter.contains("user456")); // false(可能误判)
}
}指标 | 数值 | 说明 |
|---|---|---|
插入/查询时间复杂度 | O(k) | k为哈希函数数量(通常3-10) |
空间复杂度 | O(m) | m为位数组长度(远小于哈希表) |
误判率 | 可配置(通常1%-5%) | 可通过参数调节 |
缓存穿透防护
// 查询前先检查布隆过滤器
if (!bloomFilter.contains(key)) return null; // 避免查询数据库爬虫URL去重
if (!filter.contains(url)) {
filter.add(url);
crawl(url);
}分布式系统
新手必学:
optimalSize()和optimalHashCount()理解空间与误判率的平衡
成手进阶:
动态扩容:实现自动扩容的布隆过滤器(参考Guava库)
删除支持:改造为计数布隆过滤器(牺牲空间支持删除)
class CountingBloomFilter {
private int[] countArray;
public void remove(String element) {
// 减少对应位的计数
}
}分布式扩展:设计跨节点的联合布隆过滤器(如RedisBloom)
布隆过滤器的设计体现了计算机科学的经典权衡:
正如计算机科学家 Burton Bloom 所说:“我们不需要绝对的精确,只要足够正确。” —— 这种思想在当今大数据时代愈发重要,布隆过滤器正是这一理念的完美实践。