目录
- 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!