Redis 布隆过滤器性能对比分析

redis 实现布隆过滤器实现方法:

1、redis 的 setbit 和 getbit

特点:对于某个bit 设置0或1,对于大量的值需要存储,非常节省空间,查询速度极快,但是不能查询整个key所有的bit,在一次请求有大量的值需要过滤的场景会出现多次请求getbit,性能会急剧下降,需要把多个gitbit合并成批次,使用lua脚本或者pipeline执行提高效率。

2、redis 的 BF.RESERVE,BF.MADD和 BF.MEXISTS

特点:redis 4.0 以上官方提供的一个插件,原生Bloom过滤器,参数包括 布隆过滤器的大小,误差率等,支持批量写入和批量查询,性能更优,针对一次大量请求,批量查询接口性能更快。

以上两种布隆过滤器性能测试结果对比:

硬件:单节点 redis,2G内存,2核cpu

测试条件:布隆过滤器容量都是 10000,容错率都是:0.001, 场景:一次请求需要过滤10000个id,每100个批量查询一次redis, 如此循环 10次。

序号 redis setbit getbit(时延单位:毫秒) redis BF.RESERVE,BF.MADD和 BF.MEXISTS (时延单位:毫秒)
1 1556 1238
2 1475 1164
3 1734 989
4 3034 1701
5 1532 1254
6 1579 1179
7 1541 1177
8 1567 1045
9 1698 1216
10 1689 1275
平均 1740.5 1223.8

3、基于以上的测试结果,如果一次推荐请求用户已经看过10000个视频,需要过滤10000个视频,时延会上涨到秒级以上,这样对于高并发情况性能是不行的,还有其他的办法嘛? 能不能一次性把整个布隆过滤器读到本地再进行过滤?

在推荐场景,布隆过滤器设置了容量5000个,容错率是0.001,布隆过滤器的最大值为:17972 byte,约 17K,如果每次写入和查询都查询整个布隆过滤器,1000qps 占用的网络带宽为: 13.92 Mbps。

测试可行性:本地构造一个布隆过滤器对象 BitSet,BitSet的最大值是int的最大,从redis查询出来序列化成BitSet对象,再进行读写操作,如果是写操作,再序列化写入redis。

复制代码
private BitSet get(long userId) {
    String key = TestBloomP.getBitMapKey(userId, "111");
    log.info("get bitset key:{}", key);
    return (BitSet) redisTemplate.opsForValue().get(key);
}
 
private void add(long userId, List<Long> filterItems) {
    BitSet bitSet = new BitSet();
 
    for (Long item : filterItems) {
        String uniqueKey = userId + ":" + item;
        List<Integer> offsets = TestBloomP.getOffsets(uniqueKey);
        for (Integer offset : offsets) {
            bitSet.set(offset);
        }
    }
    String key = TestBloomP.getBitMapKey(userId, "111");
    log.info("add bitset key:{}, size:{}", key, bitSet.size());
    redisTemplate.opsForValue().set(key, bitSet);
}

redis 使用java默认的序列化工具JdkSerializationRedisSerializer,测试结果 如下:写操作会先读再写 时延都是很低:

add bitset key:shop_video:filter_exposed:1607433260630157, size:143808, add count:1, time:36

get bitset time:9, bitset :143808

相关推荐
不能只会打代码6 小时前
边缘视频分析平台的架构设计与性能优化——从750ms到190ms的调优之路
java·spring boot·redis·性能优化·边缘计算·物联网竞赛
xufengzhu9 小时前
第三方 Python 库 redis-py + hiredis 的使用
开发语言·redis·python
小森林之主10 小时前
Python re 模块速查:从实战对比中掌握正则表达式
python·正则表达式·性能测试·re模块·编程实战
轻刀快马12 小时前
跨越软硬件的共鸣(二):从 Cache 写策略看 Redis 与 DB 的一致性博弈
java·开发语言·redis·计算机组成原理
程序员龙叔14 小时前
从 0 开始学习 AI 测试 - 从接口测试来教你如何用 AI 来生成自动化测试代码
自动化测试·软件测试·python·软件测试工程师·测试工具·性能测试·ai测试
lazy H14 小时前
Spring Boot 项目如何连接 Redis?新手入门配置和常见错误总结
ide·spring boot·redis·后端·学习·intellij-idea
木雷坞15 小时前
Firecrawl Docker Compose 自托管排查:镜像、Redis、队列和 Playwright
redis·docker·容器·firecrawl
柏舟飞流16 小时前
Spring Boot 进阶实战:整合 MyBatis、Redis、JWT,搭一个更像真实项目的后端服务
spring boot·redis·mybatis
南部余额17 小时前
Canal解决MySQL与Redis数据一致性问题
数据库·redis·mysql·canal·数据·数据同步
典学长编程17 小时前
Redis分布式缓存超详细教学(微服务版)!
redis·微服务·持久化·主从复制·redis哨兵集群