Bloom Filter 是一个二进制bit数组,初始为 0
用于快速查找一个集合中是否存在某个元素。尤其是大数据量中快速查找判断是否存在的问题。
布隆过滤器能记录一个元素可能存在或肯定不存在。它非常节省内存,但有一定概率会给出错误的“存在”结果,即可能出现哈希冲突,通常会使用多个不同哈希函数,对同一个值得出一组哈希值,并将这组值写入Bloom数组中,这样来降低哈希冲突的概率,如何预测误报的概率?
比如在缓存穿透场景中,当大量不存在key请求攻击时,可以使用Redis的Bloom Filter来解决。
Bloom Filter 采用位存储数据结构,节省存储空间
使用 Redisson中的布隆过滤器
使用 Redisson 创建布隆过滤器,插入元素,并检查某个元素是否存在。
在 pom.xml 文件中添加 Redisson 依赖:
1
2
3
4
5
6
7
|
<dependencies>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.16.1</version> <!-- 使用最新版本 -->
</dependency>
</dependencies>
|
编写代码来创建布隆过滤器,插入元素,并检查元素:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
import org.redisson.Redisson;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
public class RedissonBloomFilterExample {
public static void main(String[] args) {
// 配置 Redisson 客户端
Config config = new Config();
config.useSingleServer()
.setAddress("redis://127.0.0.1:6379");
// 创建 Redisson 客户端实例
RedissonClient redisson = Redisson.create(config);
// 创建布隆过滤器
RBloomFilter<String> bloomFilter = redisson.getBloomFilter("myBloomFilter");
// 初始化布隆过滤器,设置预期插入的元素数量和误报率
bloomFilter.tryInit(10000L, 0.03);
// 插入元素
bloomFilter.add("key1");
bloomFilter.add("key2");
// 查找元素
boolean mightContainYi = bloomFilter.contains("key1");
System.out.println("布隆过滤器中可能包含'key1':" + mightContainYi);
// 关闭 Redisson 客户端
redisson.shutdown();
}
}
|
布隆过滤器的Python实现示例
参考Bloom Filter !
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
import mmh3 # MurmurHash 3,常用于布隆过滤器
import math
class BloomFilter:
def __init__(self, m, k):
self.m = m # 布隆过滤器的大小(位数组的长度)
self.k = k # 哈希函数的数量
self.n = 0 # 插入的元素数量
self.bloomFilter = [0] * self.m # 初始化位数组为0
def getBitArrayIndices(self, item):
"""
计算 item 的哈希值并返回需要设置的位数组索引列表
"""
indexList = []
for i in range(1, self.k + 1):
indexList.append((hash(item) + i * mmh3.hash(item)) % self.m)
return indexList
def add(self, item):
"""
插入一个元素到布隆过滤器
"""
for i in self.getBitArrayIndices(item):
self.bloomFilter[i] = 1
self.n += 1
def contains(self, key):
"""
检查元素是否在布隆过滤器中
"""
for i in self.getBitArrayIndices(key):
if self.bloomFilter[i] != 1:
return False
return True
def generateStats(self):
"""
计算布隆过滤器的统计信息,比如错误率
"""
n = float(self.n)
m = float(self.m)
k = float(self.k)
probability_fp = math.pow((1.0 - math.exp(-(k*n)/m)), k)
print("元素数量: ", n)
print("布隆过滤器大小: ", m)
print("哈希函数数量: ", k)
print("假阳性概率: ", probability_fp)
print("假阳性率: ", probability_fp * 100.0, "%")
|
参考