本文以xx点评为例,使用redisson实现布隆过滤器
1、拉取redis
docker run --restart=always -p 6378:6379 --name myredis -d redis:7.0.12
这个命令会创建一个redis实例,如果没有找到该实例,会先联网拉取
创建成功
如果出现docker: Error response from daemon: Get "https://registry-1.docker.io/v2/":参考Error response from daemon: Get “https://registry-1.docker.io/v2/“.....解决方法-CSDN博客
查看是否创建成功
docker ps
显示
如果没有出现类似的结果,使用docker ps -a查看所有创建的容器(包括成功启动和失败的),再使用docker logs 容器名 查看创建失败的容器的日志
2、使用可视化工具连接redis
使用可视化工具连接redis,方便后续查看结果
获取redis所在服务器的ip,这里我是在虚拟机中centos7的docker中部署的,使用命令查看服务器ip
ip addr
获取红色箭头ip
redis可视化工具,这里使用的是RDM
先点击红色箭头,然后在绿色箭头输入信息,名字取啥都行(myredis),地址为上面获得的服务器的ip,还有端口号,然后点击确定即可
3、在Spring Boot项目中配置
在pom.xml文件中引入redisson依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.16.5</version>
</dependency>
在config文件夹中创建两个文件RedissonConfig和BloomFilterConfig
打开RedissonConfig,写入配置代码
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RedissonConfig {
@Bean
public RedissonClient redissonClient(){
// 配置
Config config = new Config();
config.useSingleServer().setAddress("redis://192.168.50.110:6378");
// 创建RedissonClient对象
return Redisson.create(config);
}
}
这里的ip和端口号更换为redis所在服务器的ip和redis的端口号
打开RedissonConfig,写入以下代码
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.util.List;
@Configuration
public class BloomFilterConfig {
public static final String BLOOM_FILTER_KEY = "shopBloomFilter";
private static final int EXPECTED_INSERTIONS = 100000; // 预期的ID数量
private static final double FALSE_POSITIVE_RATE = 0.01; // 误判率
@Autowired
private RedissonClient redissonClient;
@Autowired
private IShopService shopService;
@PostConstruct
public void initBloomFilter() {
// 获取布隆过滤器实例
RBloomFilter<Long> bloomFilter = redissonClient.getBloomFilter(BLOOM_FILTER_KEY);
// 如果布隆过滤器已经存在,则删除
if (bloomFilter.isExists()) {
bloomFilter.delete();
}
// 初始化布隆过滤器
bloomFilter.tryInit(EXPECTED_INSERTIONS, FALSE_POSITIVE_RATE);
// 从数据库中获取所有店铺的ID
List<Long> ids = shopService.getAllShopIds();
// 将所有ID添加到布隆过滤器中
ids.forEach(bloomFilter::add);
}
}
此处 List<Long> ids = shopService.getAllShopIds() 是自己定义的方法,获取数据库中所有店铺的id;@PostConstruct注解会使得该方法在项目启动的时候初始化,即项目启动后,布隆过滤器会先加载所有id。
4、在业务代码中使用
这里在xx点评中的queryById中使用
5、测试布隆过滤器
配置完后,启动项目测试
布隆过滤器初始化成功,查看RDM可视化工具
创建了一个布隆过滤器且有数据。
使用postman调用查询id的接口,如下
id为70数据并不在数据库里,所有直接在布隆过滤器这一层就拦截了
id为1的数据,数据库中存在,查询成功!