布隆过滤器

什么是布隆过滤器?

布隆过滤器是一种数据结构,用于快速判断一个元素是否存在于一个集合中。

使用场景

✨初始使用:注册用户时就向容器中新增数据,就不需要任务向容器存储数据了。
✨使用过程中引入:读取数据源将目标数据刷到布隆过滤器。

缺点

可能存在一定的误判。

代码中使用Redis自带的布隆过滤器

1️⃣在子工程的pom.xml文件中引入Redisson依赖(由于在父工程中定义了相关依赖的版本号,所以此处不需要指定version)
1
2
3
4
5
6
7
8
9
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
</dependency>
2️⃣在子工程的application.yaml文件中配置 Redis 参数(根据自己的参数来修改)
1
2
3
4
5
6
spring:
data:
redis:
host: 127.0.0.1
port: 6379
password: xxxx
3️⃣创建布隆过滤器配置类实例(自定义布隆过滤器的名字userRegisterCachePenetrationBloomFilter)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 布隆过滤器配置
*/
@Configuration
public class RBloomFilterConfiguration {

/**
* 防止用户注册查询数据库造成缓存穿透的布隆过滤器
*/
@Bean
public RBloomFilter<String> userRegisterCachePenetrationBloomFilter(RedissonClient redissonClient) {
RBloomFilter<String> cachePenetrationBloomFilter = redissonClient.getBloomFilter("userRegisterCachePenetrationBloomFilter");
cachePenetrationBloomFilter.tryInit(100000000L, 0.001);
return cachePenetrationBloomFilter;
}
}
👉tryInit 有两个核心参数需要自行设置:
expectedInsertions:预估布隆过滤器存储的元素长度。
falseProbability:运行的误判率。
🧷计算布隆过滤器占用内存大小的在线网站

4️⃣代码中使用(引入lombok依赖,使用构造器方式注入)

1
2
3
4
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor

private final RBloomFilter<String> userRegisterCachePenetrationBloomFilter;

5️⃣代码改造
❌原代码

1
2
3
4
5
6
7
@Override
public Boolean hasUsername(String username) {
LambdaQueryWrapper<UserDO> queryWrapper = Wrappers.lambdaQuery(UserDO.class)
.eq(UserDO::getUsername, username);
UserDO userDO = baseMapper.selectOne(queryWrapper);
return userDO == null;
}

✅改进版

1
2
3
4
@Override
public Boolean hasUsername(String username) {
return !userRegisterCachePenetrationBloomFilter.contains(username);
}