提要
布隆过滤器(Bloom Filter)相信大家都听说过,不了解的朋友可以参考我之前的文章《布隆过滤器简介》。那么在Java项目中怎样使用布隆过滤器呢,下面就简单介绍下。
一. 使用Guava中提供的布隆过滤器
Guava是一套Google开源的Java库,它提供了很多简化编程的工具类,其中就包括了布隆过滤器。
使用方式
在项目中添加依赖<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>29.0-jre</version> </dependency>代码示例
package com.example; import com.google.common.Hash.BloomFilter; import com.google.common.hash.Funnels; import java.nio.charset.Charset; /** * 使用Guava提供的布隆过滤器 */ public class GuavaBloomFilter { // 预计存储元素的个数 private static final int expectedInsertions = 10000; // 误判率 private static final double fpp = 0.03; public static void main(String[] args) { // 创建布隆过滤器 BloomFilter<CharSequence> bloomFilter = BloomFilter.create( Funnels.stringFunnel(Charset.defaultCharset()), expectedInsertions, fpp); // 存入元素 bloomFilter.put("张三"); bloomFilter.put("李四"); System.out.println("大约存储元素的个数:" + bloomFilter.approximateElementCount()); // 检索元素 System.out.println("检索张三是否存在:" + bloomFilter.mightContain("张三")); System.out.println("检索王五是否存在:" + bloomFilter.mightContain("王五")); } }
注意:Guava提供的布隆过滤器只能应用在单体应用中,因为这种方式创建的过滤器是存储在应用内存中的,所以在分布式环境下不适用。
二. 使用redis中加载的布隆过滤器模块
在分布式环境下,使用Redis存储布隆过滤器就是个不错的选择。从Redis4.0版本开始,可以通过加载Redis实验室提供的布隆过滤器模块,使Redis中具有布隆过滤器类型。
使用此种方式操作布隆过滤器有个必要的前提:Redis Server必须加载布隆过滤器模块。加载 可以参考我之前的文章《Redis加载布隆过滤器模块》。
一般我们在Java项目中连接Redis时通常是使用Jedis客户端,但是目前Jedis中没有提供对Redis扩展模块的命令的封装,所以我们必须使用Redis实验室提供的专门操作扩展模块的客户端。
使用方式
在项目中添加依赖<dependency> <groupId>com.redislabs</groupId> <artifactId>jrebloom</artifactId> <version>2.1.0</version> </dependency>代码示例
package com.example; import io.rebloom.client.Client; import io.rebloom.Client.ClusterClient; import redis.clients.jedis.HostAndPort; import java.util.HashSet; import java.util.Set; /** * 使用Redis布隆过滤器模块 */ public class RedisModuleBloomFilter { // 容量 private static final long initCapacity = 10000L; // 误判率 private static final double errorRate = 0.03; private static final String FILTER_NAME = "BF:name" public static void main(String[] args) { // 初始化客户端 Client client = new Client("localhost", 6379); // // 初始化集群客户端 // Set<HostAndPort> ClusterNodes = new HashSet<>(); // clusterNodes.add(new HostAndPort("localhost", 6379)); // ClusterClient client = new ClusterClient(clusterNodes); // 创建布隆过滤器;该 只能调用一次,如果同名过滤器已存在,将抛出异常 client.createFilter(FILTER_NAME, initCapacity, errorRate); // 添加单个元素 client.add(FILTER_NAME, "mark"); // 添加多个元素 client.addMulti(FILTER_NAME, "foo", "bar", "baz", "bat", "bag"); // 检查元素是否存在 System.out.println(client.exists(FILTER_NAME, "mark")); System.out.println(client.exists(FILTER_NAME, "foot")); } }
三. 使用Redisson提供的基于Redis布隆过滤器
Redisson是一款功能强大且简单易用的Java语言的Redis客户端。
强烈建议没有使用过的朋友可以学习一下。GitHub地址:https://github.com/redisson/redisson。值得一提的是,该项目还提供了中文文档(https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95),这对英文不好的朋友可以说是很大的福音了。
使用redisson客户端提供的布隆过滤器功能可以直接在Redis中创建及使用布隆过滤器,无需在Redis Server中加载扩展模块。
使用方式
在项目中添加依赖<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.13.6</version> </dependency>代码示例
package com.example; import org.redisson.Redisson; import org.redisson.api.RBloomFilter; import org.redisson.api.RedissonClient; import org.redisson.config.Config; /** * 使用redisson布隆过滤器 */ public class RedissonBloomFilter { // 预计存储元素的个数 private static final long expectedInsertions = 10000L; // 误判率 private static final double fpp = 0.03; private static final String FILTER_NAME = "BF:name"; public static void main(String[] args) { // 创建redisson连接 Config config = new Config(); config.useSingleServer().setTimeout(1000000).setAddress("redis://localhost:6379"); RedissonClient redissonClient = Redisson.create(config); // 创建布隆过滤器并初始化 RBloomFilter<String> bloomFilter = redissonClient.getBloomFilter(FILTER_NAME); bloomFilter.tryInit(expectedInsertions, fpp); // 存入元素 bloomFilter.add("张三"); bloomFilter.add("李四"); // 检索元素是否存在 System.out.println(bloomFilter.contains("张三")); System.out.println(bloomFilter.contains("王五")); // 关闭连接 redissonClient.shutdown(); } }