Redisson实战-BloomFilter
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的更多相关文章
- 别再用 Redis List 实现消息队列了,Stream 专为队列而生
上回说到使用 Redis 的 List 实现消息队列有很多局限性,比如: 没有良好的 ACK 机制: 没有 ConsumerGroup 消费组概念: 消息堆积. List 是线性结构,想要查询指定数据 ...
- Redis HyperLogLog 是什么?这些场景使用它,让我枪出如龙,一笑破苍穹
在移动互联网的业务场景中,数据量很大,我们需要保存这样的信息:一个 key 关联了一个数据集合,同时对这个数据集合做统计. 比如: 统计一个 APP 的日活.月活数: 统计一个页面的每天被多少个不同账 ...
- Redisson 分布式锁实战与 watch dog 机制解读
Redisson 分布式锁实战与 watch dog 机制解读 目录 Redisson 分布式锁实战与 watch dog 机制解读 背景 普通的 Redis 分布式锁的缺陷 Redisson 提供的 ...
- Redis实战篇
Redis实战篇 1 Redis 客户端 1.1 客户端通信 原理 客户端和服务器通过 TCP 连接来进行数据交互, 服务器默认的端口号为 6379 . 客户端和服务器发送的命令或数据一律以 \r\n ...
- redis(7)--redis应用实战
问题1:哨兵模式下客户端应该连接哪个redis-server? 问题2:集群模式下为什么会有MOVED error Redis Java客户端介绍 已有的客户端支持 Redis Java客户端有很多的 ...
- 硬核 | Redis 布隆(Bloom Filter)过滤器原理与实战
在Redis 缓存击穿(失效).缓存穿透.缓存雪崩怎么解决?中我们说到可以使用布隆过滤器避免「缓存穿透」. 码哥,布隆过滤器还能在哪些场景使用呀? 比如我们使用「码哥跳动」开发的「明日头条」APP 看 ...
- (转)国内外三个不同领域巨头分享的Redis实战经验及使用场景
随着应用对高性能需求的增加,NoSQL逐渐在各大名企的系统架构中生根发芽.这里我们将为大家分享社交巨头新浪微博.传媒巨头Viacom及图片分享领域佼佼者Pinterest带来的Redis实践,首先我们 ...
- 【原】实战-Java如何使用Redis
实战-Java如何使用Redis Redis的Client支持的语言非常丰富,如下: ActionScript Bash C C# C++ Clojure Common Lisp Crystal D ...
- Hbase 设计与开发实战
Hbase 概述 大数据及 NoSQL 的前世今生 传统的关系型数据库处理方式是基于全面的 ACID 保证,遵循 SQL92 的标准表设计模式(范式)和数据类型,基于 SQL 语言的 DML 数据交互 ...
随机推荐
- CentOS-GitLab迁移(yum至Docker)
yum备份迁移Docker版的GitLab 注:确保版本一致 1.yum备份 $ gitlab-rake gitlab:backup:create 2.执行完成后,在/var/opt/gitlab/b ...
- Docker:Linux离线安装docker
docker离线下载路径 docker所有版本:https://download.docker.com/linux/static/stable/ 离线安装 1.解压 #解压tar包 tar -xvf ...
- 5shell中的数组
0.理解数组 (1)shell不限制数组的大小,数组元素的下标从0开始计数 (2)获取数组中的元素要使用下标[ ],下标可以是一个整数,也可以是一个结果为整数的表达式,但是下标必须大于等于0 (3)b ...
- Linux相关网络命令大全 网络接口 域名分析
Linux网络设置一.查看网络接口信息ifconfig① 查看所有活动的网络接口信息② 查看指定网络接口信息补充二.查看主机名称hostname① hostname命令② 永久设置主机名三.查看路由表 ...
- SpringMVC中@Controller和@RequestMapping用法
一.简介 在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Mo ...
- Spring Boot邮箱链接注册验证
Spring Boot邮箱链接注册验证 简单介绍 注册流程 [1]前端提交注册信息 [2]后端接受数据 [3]后端生成一个UUID做为token,将token作为redis的key值,用户数据作为re ...
- Python+Requests+Xpath(解析)爬取某站点简历图片(数据分析三)
1.环境安装 pip install lxml 2.解析原理 使用通用爬虫爬取网页数据 实例化etree对象,且将页面数据加载到该对象中 使用xpath函数结合xpath表达式进行标签定位和指定数据提 ...
- springboot-7-WebSocket
一.WebSocket简介 为什么要什么websocket:https://blog.csdn.net/qq_42429911/article/details/88601279 用websocket可 ...
- 40.qt quick- 高仿微信实现局域网聊天V4版本(支持gif动图表情包、消息聊天、拖动缩放窗口)
在上章37.qt quick- 高仿微信实现局域网聊天V3版本(添加登录界面.UDP校验登录.皮肤更换.3D旋转),我们已经实现了: 添加登录界面. UDP校验登录. 皮肤更换. 3D旋转(主界面和登 ...
- Linux文件浏览(less、more、head、tail)以及vim编辑器命令总结
结合小编学习实践,整理了Linux下查看内容(less.more.head.tail)和编辑内容(vim)的部分基础命令解析: 1.less命令 分页浏览内容,如果在shell命令行下按回车键,则一点 ...