1. 简介

布隆过滤器是防止缓存穿透的方案之一。布隆过滤器主要是解决大规模数据下不需要精确过滤的业务场景,如检查垃圾邮件地址,爬虫URL地址去重, 解决缓存穿透问题等。

布隆过滤器:在一个存在一定数量的集合中过滤一个对应的元素,判断该元素是否一定不在集合中或者可能在集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难

想详细了解的,可以查看我的另一篇博客Redis-缓存穿透/击穿/雪崩

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没法比。

Redisson实战-BloomFilter的更多相关文章

  1. 别再用 Redis List 实现消息队列了,Stream 专为队列而生

    上回说到使用 Redis 的 List 实现消息队列有很多局限性,比如: 没有良好的 ACK 机制: 没有 ConsumerGroup 消费组概念: 消息堆积. List 是线性结构,想要查询指定数据 ...

  2. Redis HyperLogLog 是什么?这些场景使用它,让我枪出如龙,一笑破苍穹

    在移动互联网的业务场景中,数据量很大,我们需要保存这样的信息:一个 key 关联了一个数据集合,同时对这个数据集合做统计. 比如: 统计一个 APP 的日活.月活数: 统计一个页面的每天被多少个不同账 ...

  3. Redisson 分布式锁实战与 watch dog 机制解读

    Redisson 分布式锁实战与 watch dog 机制解读 目录 Redisson 分布式锁实战与 watch dog 机制解读 背景 普通的 Redis 分布式锁的缺陷 Redisson 提供的 ...

  4. Redis实战篇

    Redis实战篇 1 Redis 客户端 1.1 客户端通信 原理 客户端和服务器通过 TCP 连接来进行数据交互, 服务器默认的端口号为 6379 . 客户端和服务器发送的命令或数据一律以 \r\n ...

  5. redis(7)--redis应用实战

    问题1:哨兵模式下客户端应该连接哪个redis-server? 问题2:集群模式下为什么会有MOVED error Redis Java客户端介绍 已有的客户端支持 Redis Java客户端有很多的 ...

  6. 硬核 | Redis 布隆(Bloom Filter)过滤器原理与实战

    在Redis 缓存击穿(失效).缓存穿透.缓存雪崩怎么解决?中我们说到可以使用布隆过滤器避免「缓存穿透」. 码哥,布隆过滤器还能在哪些场景使用呀? 比如我们使用「码哥跳动」开发的「明日头条」APP 看 ...

  7. (转)国内外三个不同领域巨头分享的Redis实战经验及使用场景

    随着应用对高性能需求的增加,NoSQL逐渐在各大名企的系统架构中生根发芽.这里我们将为大家分享社交巨头新浪微博.传媒巨头Viacom及图片分享领域佼佼者Pinterest带来的Redis实践,首先我们 ...

  8. 【原】实战-Java如何使用Redis

    实战-Java如何使用Redis Redis的Client支持的语言非常丰富,如下: ActionScript Bash C C# C++ Clojure Common Lisp Crystal D ...

  9. Hbase 设计与开发实战

    Hbase 概述 大数据及 NoSQL 的前世今生 传统的关系型数据库处理方式是基于全面的 ACID 保证,遵循 SQL92 的标准表设计模式(范式)和数据类型,基于 SQL 语言的 DML 数据交互 ...

随机推荐

  1. thinkphp5.0 QQ第三方登录详解

    一.前期准备工作 到QQ互联官网进行开发资质认证,并创建网站应用.获取到appid和appkey后,下载demo文件. demo文件下载方式:QQ互联>文档资料>SDK及资源下载>p ...

  2. MySql:mysql修改密码及配置远程连接

    通过配置文件修改 mysql5.7  mysql库下面的user表没有password字段无法修改密码,5.7版本已经不再使用password来作为密码的字段了  而改成了authentication ...

  3. 其他:Spring5.0框架源码导入IDEA

    1.下载Spring spring-framework-5.0.4.RELEASE下载地址:https://github.com/spring-projects/spring-framework/re ...

  4. 多es 集群数据迁移方案

    前言 加入新公司的第二个星期的星期二 遇到另一个项目需要技术性支持:验证es多集群的数据备份方案,需要我参与验证,在这个项目中需要关注到两个集群的互通性.es集群是部署在不同的k8s环境中,K8s环境 ...

  5. mac-webui-selenium下的webdriver selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable needs to be in PATH

    from selenium import webdriver def test1(): url='http://www.baidu.com' driver=webdriver.Chrome(" ...

  6. python使用笔记22--mock接口开发

    1.mock接口开发 mock是模拟一个接口的意思 为了不阻止测试,开发一个接口,返回你想要的数据,模拟各种场景 需要安装第三方模块flask,flask是web轻量级开发框架 1.1 flask p ...

  7. AI 预测蛋白质结构「GitHub 热点速览 v.21.29」

    作者:HelloGitHub-小鱼干 虽然 AI 领域藏龙卧虎,但是本周预测蛋白质结构的 alphafold 一开源出来就刷爆了朋友圈,虽然项目与我无关,但是看着科技进步能探寻到生命机理,吃瓜群众也有 ...

  8. 1.在配置XML文件时出现reference file contains errors (http://www.springframework.org/schema/beans/...解决方案

    解决方案: 第一步:将 Preferences > XML > XML Files > Validation中"Honour all XML schema location ...

  9. Jmeter性能测试指标分析

    一.Aggregate Report 是 JMeter 常用的一个 Listener,中文被翻译为"聚合报告 如果大家都是做Web应用的性能测试,例如访问百度请求为例,线程10,循环10次, ...

  10. 【模拟】选数 luogu-1037

    AC代码 #include <bits/stdc++.h> using namespace std; #define ms(a,b) memset(a,b,sizeof(a)) typed ...