目录
- 1. 简介
- 2. guava 实现
- 2.1 导入依赖
- 2.2 bloomfiltertest
- 2.3 启动测试
- 2.4 小节
- 3. redisson 实现
- 3.1 导入依赖
- 3.2 bloomfilterwithredisson
- 3.3 启动测试
1. 简介
布隆过滤器是防止缓存穿透的方案之一。布隆过滤器主要是解决大规模数据下不需要精确过滤的业务场景,如检查垃圾邮件地址,爬虫url地址去重, 解决缓存穿透问题等。
布隆过滤器:在一个存在一定数量的集合中过滤一个对应的元素,判断该元素是否一定不在集合中或者可能在集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。
2. guava 实现
google的guava工具类已经帮我们造好了轮子,通过实例来感受一下。
2.1 导入依赖
<dependency> <groupid>com.google.guava</groupid> <artifactid>guava</artifactid> <version>30.1.1-jre</version> </dependency>
2.2 bloomfiltertest
import com.google.common.hash.bloomfilter;
import com.google.common.hash.funnels;
import lombok.extern.slf4j.slf4j;
/**
* 布隆过滤器简单实现
* @author ludangxin
* @date 2021/8/16
*/
@slf4j
public class bloomfiltertest {
/**
* 预计要插入元素个数
*/
private static final int size = 1000000;
/**
* 误判率
*/
private static final double fpp = 0.01;
/**
* 布隆过滤器
*/
private static final bloomfilter<integer> bloomfilter = bloomfilter.create(funnels.integerfunnel(), size, fpp);
public static void main(string[] args) {
//插入数据
for (int i = 0; i < 1000000; i++) {
bloomfilter.put(i);
}
int count = 0;
// 过滤判断
for (int i = 1000000; i < 3000000; i++) {
if (bloomfilter.mightcontain(i)) {
count++;
log.info(i + "误判了");
}
}
log.info("总共的误判数:" + count);
}
}
2.3 启动测试
如上代码,我们设置了0.01的误差,过滤判断时从1000000到3000000,误判了2 * 20000000 ≈ 20339 符合预期。
…..
21:40:21.529 [main] info com.ldx.redisson.controller.bloomfiltertest – 2999004误判了
21:40:21.529 [main] info com.ldx.redisson.controller.bloomfiltertest – 2999045误判了
21:40:21.529 [main] info com.ldx.redisson.controller.bloomfiltertest – 2999219误判了
21:40:21.529 [main] info com.ldx.redisson.controller.bloomfiltertest – 2999699误判了
21:40:21.529 [main] info com.ldx.redisson.controller.bloomfiltertest – 2999753误判了
21:40:21.529 [main] info com.ldx.redisson.controller.bloomfiltertest – 2999838误判了
21:40:21.529 [main] info com.ldx.redisson.controller.bloomfiltertest – 2999923误判了
21:40:21.529 [main] info com.ldx.redisson.controller.bloomfiltertest – 2999928误判了
21:40:21.529 [main] info com.ldx.redisson.controller.bloomfiltertest – 总共的误判数:20339
2.4 小节
guava的工具包虽然好用,但是数据集是存储在jvm中的,分布式环境下依然没法使用。
3. redisson 实现
3.1 导入依赖
<dependency> <groupid>org.redisson</groupid> <artifactid>redisson-spring-boot-starter</artifactid> <version>3.16.1</version> </dependency>
3.2 bloomfilterwithredisson
import lombok.requiredargsconstructor;
import lombok.extern.slf4j.slf4j;
import org.redisson.api.rbloomfilter;
import org.redisson.api.redissonclient;
import org.springframework.web.bind.annotation.getmapping;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;
/**
* redisson 布隆过滤器实现
*
* @author ludangxin
* @date 2021/8/16
*/
@slf4j
@restcontroller
@requestmapping("bloomfilter")
@requiredargsconstructor
public class bloomfilterwithredisson {
private final redissonclient redissonclient;
/**
* 预计要插入元素个数
*/
private static final long size = 1000000l;
/**
* 误判率
*/
private static final double fpp = 0.01;
/**
* 自定义布隆过滤器的 key
*/
private static final string bloom_filter_key = "bloomfilter";
/**
* 向布隆过滤器中添加数据, 模拟向布隆过滤器中添加10亿个数据
*/
@getmapping
public void filter() {
// 获取布隆过滤器
rbloomfilter<integer> bloomfilter = redissonclient.getbloomfilter(bloom_filter_key);
// 初始化,容量为100万, 误判率为0.01
bloomfilter.tryinit(size, fpp);
// 模拟向布隆过滤器中添加100万个数据
for (int i = 0; i < size; i++) {
bloomfilter.add(i);
}
int count = 0;
// 过滤判断
for (int i = 1000000; i < 3000000; i++) {
if (bloomfilter.contains(i)) {
count++;
log.info(i + "误判了");
}
}
log.info("size:" + bloomfilter.getsize());
log.info("总共的误判数:" + count);
}
}
3.3 启动测试
由于机器性能有限,又是单机环境,所以程序没有跑完。
但由此也可以看出,基于redis的布隆过滤器虽然解决了分布式问题,但是性能和guava bloomfilter没法比。
到此这篇关于redis bloomfilter实例讲解的文章就介绍到这了,更多相关redis bloomfilter实例内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!