目录
布隆过滤器介绍
布隆过滤器由「初始值都为 0 的位图数组」和「 N 个哈希函数」两部分组成。当我们在写入数据库数据时,在布隆过滤器里做个标记,这样下次查询数据是否在数据库时,只需要查询布隆过滤器,如果查询到数据没有被标记,说明不在数据库中。
布隆过滤器会通过 3 个操作完成标记:
-
第一步,使用 N 个哈希函数分别对数据做哈希计算,得到 N 个哈希值。
-
第二步,将第一步得到的 N 个哈希值对位图数组的长度取模,得到每个哈希值在位图数组的对应位置。
-
第三步,将每个哈希值在位图数组的对应位置的值设置为 1。
工作流程图如下:
优点:
- 插入和查询操作都非常高效,时间复杂度为 O(k),其中 kkk 是哈希函数的数量。
- 使用位数组来存储数据,能够在非常小的内存占用下表示大量数据。
缺点:
- 存在误判的可能性,例如数据x和数据y经过hash运算后可能都落在位数组1、4、6的位置上,但是数据库中其实并没有数据y。
- 不支持从删除元素
使用场景
- 缓存穿透:我们可以在写入数据库数据时,使用布隆过滤器做个标记,然后在用户请求到来时,业务线程确认缓存失效后,可以通过查询布隆过滤器快速判断数据是否存在,如果不存在,就不用通过查询数据库来判断数据是否存在。
- 数据去重:在大数据处理和分析中,布隆过滤器可以用于快速检测数据集中是否存在重复数据,它可以用于在数据导入过程中去除重复数据,减少存储和处理的开销。
- 黑名单:在网络安全中,布隆过滤器可以用来维护一个黑名单,快速判断某个IP地址是否已知的恶意地址,从而阻止访问。
实战
引入相关依赖:
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.17.5</version>
</dependency>
yml相关配置:
spring:
redis:
host: 114.132.86.18
port: 6379
相关配置类:
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.redis")
public class RedissonConfig {
private String host;
private Integer port;
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://" + host + ":" + port);
return Redisson.create(config);
}
}
@Configuration(value = "rBloomFilterConfigurationByAdmin")
public class RBloomFilterConfiguration {
@Bean
public RBloomFilter<String> userBloomFilter(RedissonClient redissonClient) {
RBloomFilter<String> cachePenetrationBloomFilter = redissonClient.getBloomFilter("userBloomFilter");
// 100000000L 表示预期要插入的元素数量,0.001 表示目标误判率
cachePenetrationBloomFilter.tryInit(100000000L, 0.001);
return cachePenetrationBloomFilter;
}
}
测试:
@SpringBootTest
class Demo1ApplicationTests {
@Resource
private RBloomFilter<String> userBloomFilter;
@Test
void contextLoads() {
// 向布隆过滤器添加元素
userBloomFilter.add("test");
// 判断是否存在布隆过滤器
if (!userBloomFilter.contains("test")) {
System.out.println("当前值不存在布隆过滤器");
}else{
System.out.println("当前值存在布隆过滤器");
}
}
}
结果: