【应用】布隆过滤器

news2024/11/13 8:53:21

布隆过滤器

  • 布隆过滤器简介及使用场景
  • 布隆过滤器底层原理
    • 数据添加
    • 数据查询
    • 布隆过滤器的优缺点
  • Redis 整合布隆过滤器
  • Java 整合布隆过滤器
  • SpringBoot 整合 Redis 使用布隆过滤器

布隆过滤器简介及使用场景

布隆过滤器实际上是一列很长的二进制数组,在每个位置上只有 0 和 1两种可能,其出现的意义在于快速判断某个元素是否存在。

布隆过滤器可以判断某个元素一定不存在或者可能存在,这与其底层的实现原理有关,利用其可以判断元素一定不存在的特性,可以解决开发中的很多问题,如 redis 的缓存穿透问题。

布隆过滤器底层原理

数据添加

布隆过滤器的底层原理可以简单地理解为”二进制数组 + 若干哈希函数“,二进制数组的长度与哈希函数的数量决定了布隆过滤器在判断元素存在时的误判率。

当我们往布隆过滤器中存放元素时,会利用每一个哈希函数对相应元素进行处理,每一次的处理都会得到一个值,将处理后的值对数组长度取模便得到该元素在数组中的一个位置,该过程类似于向 HashMap 中添加数据。

所有的哈希函数处理后得到的一组“位置”即定义了该元素在布隆过滤器中的存在,将二进制数组的对应位置标志为 1。

整个添加元素的过程如下图所示:

在这里插入图片描述

数据查询

基于上述添加元素的原理,进行元素是否存在的判断,即通过哈希函数计算对应的位置组,若对应位置组的值均为 1,则证明该元素可能存在(因为可能存在哈希冲突);若对应位置组的值存在 0,则证明该元素一定不存在。

因此,若要求误判率越小,则位数组就越长,空间的占用就越大;同时哈希函数的数量也就越多,计算的耗时也就越长。误判率本质上就是哈希冲突的概率。Bloom Filter Calculator可以根据数组长度与误判率计算布隆过滤器的哈希函数数量以及数组长度。

布隆过滤器的优缺点

  • 优点:

    • 增加和查询元素的时间复杂度小,为 O(N),其中 N 为哈希函数的数量;

    • 数据保密性强,因为布隆过滤器不保存数据本身,而是保存的“位置信息”;

    • 占用空间较小

  • 缺点:

    • 存在误判的可能,可以通过调整参数来降低误判率,但会增大空间占用和计算时间;

    • 无法在布隆过滤器中获取元素本身,同时很难删除元素;

Redis 整合布隆过滤器

此处直接使用官方提供的整合了布隆过滤器的 redis 镜像进行测试,使用下列语句启动容器

docker run -p 6379:6379 \
> --name rebloom \
> -d --restart=always \
> -e TZ="Asia/Shanghai" \
> -v /root/rebloom/conf/redis.conf:/usr/local/etc/redis/redis.conf \
> -v /root/rebloom/data:/var/lib/redis \
> -v /root/rebloom/log:/var/log/redis \
> redislabs/rebloom:2.2.2

容器启动成功后进入容器,登录 redis 客户端

docker exec -it rebloom /bin/bash
root@75acaeca6568:/data# redis-cli
127.0.0.1:6379>

向布隆过滤器中添加元素:BF.ADD key ...options...

127.0.0.1:6379> BF.ADD testKey key1
(integer) 1
127.0.0.1:6379> BF.ADD testKey key2
(integer) 1

向布隆过滤器中批量添加元素:BF.MADD key ...options...

127.0.0.1:6379> BF.MADD testKey key3 key4 key5
1) (integer) 1
2) (integer) 1
3) (integer) 1

在布隆过滤器中查询元素是否存在:BF.EXISTS key ...options...(存在则返回 1;不存在则返回 0)

127.0.0.1:6379> BF.EXISTS testKey key4
(integer) 1
127.0.0.1:6379> BF.EXISTS testkey key8
(integer) 0

在布隆过滤器中批量查询元素是否存在:BF.MEXISTS key ...options...

127.0.0.1:6379> BF.MEXISTS testKey key1 key2 key3 key9
1) (integer) 1
2) (integer) 1
3) (integer) 1
4) (integer) 0

Java 整合布隆过滤器

此处使用谷歌 guava 包中实现的布隆过滤器进行测试,引入相应的依赖

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>29.0-jre</version>
</dependency>

编写 Java 程序实例化布隆过滤器对象并使用

public class BloomFilterDemo {

    public static void main(String[] args) {
        // 定义预计插入的数据量
        int expectedInsertions = 10000000;
        // 定义误判率
        double fpp = 0.01;
        /**
         * 生成布隆过滤器对象
         * 主要参数:
         * Funnel<? super T> funnel:数据类型,由 Funnels 类指定
         * int expectedInsertions:预计插入数量
         * double fpp:误判率
         * BloomFilter.Strategy strategy:hash 策略
         */
        BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charset.defaultCharset()),
                expectedInsertions, fpp);
        // 向布隆过滤器中添加一千万数据
        for (int i = 0; i < expectedInsertions; i++) {
            bloomFilter.put("test" + i);
        }
        // 使用一千万数据进行测试,计算误判数量以及误判率
        double count = 0;
        for (int i = expectedInsertions; i < expectedInsertions * 2; i++) {
            if (bloomFilter.mightContain("test" + i)) {
                count++;
            }
        }
        System.out.println(">>>误判数量为:" + count);
        System.out.println(">>>误判率为:" +  count / expectedInsertions);
    }

}

输出结果如下,实际的误判率与我们设置的误判率几乎相同

>>>误判数量为:100936.0
>>>误判率为:0.0100936

SpringBoot 整合 Redis 使用布隆过滤器

使用轻量级的连接包 redission 实现,引入依赖

<dependency>
  <groupId>org.redisson</groupId>
  <artifactId>redisson-spring-boot-starter</artifactId>
  <version>3.16.0</version>
</dependency>

编写代码,连接 Redis 服务并测试使用布隆过滤器

public class BloomFilterDemo2 {

    public static void main(String[] args) {
        // 定义预计插入的数据量
        long expectedInsertions = 10;
        // 定义误判率
        double fpp = 0.01;
        // 配置 redis 服务地址
        Config redisConfig = new Config();
        redisConfig.useSingleServer().setAddress("redis://47.92.146.85:6379");
        // 构建 redis-cli
        RedissonClient redissonClient = Redisson.create(redisConfig);
        // 生成并初始化布隆过滤器
        RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter("username");
        bloomFilter.tryInit(expectedInsertions, fpp);
        // 向布隆过滤器中添加对象
        for (int i = 0; i < expectedInsertions; i++) {
            bloomFilter.add("username" + i);
        }
        // 验证对象是否存在
        System.out.println(bloomFilter.contains("username1")); // true
        System.out.println(bloomFilter.contains("username11")); // false
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/60652.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CommonsCollections4利用链分析

目录 前言&#xff1a; 0x01 代码分析 总结一下利用链&#xff1a; POC: 完整的POC&#xff1a; 图 1-1 cc利用链前言&#xff1a; CC4这条链用到了新的Commons-Collections4这个依赖&#xff0c;由于这个依赖与之前的版本具有较大的出入&#xff0c;连groupId和artifactId…

Android 基础知识4-2.1常用控件文本框(TextView)

TextView就是用来显示文本标签的控件&#xff0c;修改使用TextView显示文本的颜色、大小等属性。 实例代码&#xff1a; xml&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.co…

有源晶振与无源晶振的区别

今天就来和大家分享下有源晶振和无源晶振的区别。 1.从外形上有源大部分有源晶振是这种四脚贴片的&#xff0c;差分有源晶振的话一般是6脚的&#xff0c;当然还有其它的一些封装 而无源晶振的有两脚插件的也有和有源晶振一样的这种四脚贴片的 2.无源晶振不需要额外供电&#x…

.移动端适配的解决方案

何为移动端适配 移动端适配就是值在不同的移动端 可以去讲我们的内容适应不同屏幕尺寸大小 我们之前写单位用的是px这个单位 但是这是一个写死的单位 rem 所以我们用一个可变的单位 rem &#xff08;是指用html字体大小作为单位 比如说我们设置html字体大小为16px 那么 …

[附源码]计算机毕业设计基于springboot的残障人士社交平台

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

一篇文章了解MySQL的group by

准备工作&#xff01; 1.本文章MySQL使用的是5.7&#xff0c;引擎使用的是innodb 2. 使用的表结构&#xff08;t1&#xff09;&#xff0c;字段a上有一个索引&#xff0c; 1. group by常用方法&#xff1a; group by的常规用法是配合聚合函数&#xff0c;利用分组信息进行统…

公众号网课查题接口使用方法

公众号网课查题接口使用方法 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 题库&#xff1a;题库后台&#xff08;点击跳转&…

用Hopper修改代理软件端口

背景 用代理软件可以访问google&#xff0c;但是端口经常不固定&#xff0c;从缺省1080变成了随机。 前几天其实已经用Hopper 3.0看了一次&#xff0c;但是好像不支持go&#xff0c;所以没反编译成功&#xff0c;这次换了4.0&#xff0c;支持了go。 Hopper与逆向 逆向的目的…

7.7 网络(二)

接上篇&#xff1a;7.7 网络&#xff08;一&#xff09;_龙赤子的博客-CSDN博客 目录 三 操作系统涉及的网络内容 1 网络栈 2 协议 3 应用 三 操作系统涉及的网络内容 1 网络栈 这里我们重点讨论操作系统里面的网络。这部分在整个网络架构中&#xff0c;属于端的技术。对于端来…

Spring - ApplicationContextAwareProcessor扩展接口

文章目录Preorg.springframework.context.support.ApplicationContextAwareProcessor内部的7个扩展点源码解析扩展示例Pre Spring Boot - 扩展接口一览 org.springframework.context.support.ApplicationContextAwareProcessor /** Copyright 2002-2020 the original author …

python中xpath解析

**前言&#xff1a;**今年博客更新的太少了&#xff0c;很多学习计划都因为工作原因延迟了&#xff0c;今年真的身心太疲惫了&#xff0c;终于有点能理解为什么有的同行们会无心学习了&#xff0c;今年同样也是吃老本的一篇博客&#xff0c;所谓好记性不如烂笔头&#xff0c;以…

Java中静态域和静态方法的一些梳理

最近发现自己对一些Java中的静态域和静态方法的基础知识掌握的不是特别牢靠&#xff0c;于是针对一些自己之前模棱两可的点&#xff0c;进行书籍的翻阅复习。 参考文献&#xff1a; Java核心技术卷一 静态域 将域定义为static&#xff0c;代表该类的所有实例对象都共享这一个…

[附源码]计算机毕业设计JAVA医药管理系统

[附源码]计算机毕业设计JAVA医药管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis M…

QT5.14.2+cmake3.8.2+opencv3.4.0环境配置遇到的问题

1、cmke的configure时遇到无法下载opencv_ffmpeg.dll等三个文件 我直接用网上的下载好的在文件夹中添加&#xff0c;不过&#xff0c;一定要改成原文件的命名&#xff0c;就是带一堆数字签名的&#xff1a; 然后直接Generate,之后就可以去cmd编译了 &#xff08;因为再次conf…

RocketMq消息持久化(一)——存储架构设计概述

1.RocketMq 存储概要设计 RocketMQ主要存储的文件包括Comitlog文件、ConsumeQueue文件、IndexFile文件&#xff0c;存储路径为${ROCKET_HOME}/store&#xff0c;默认在当前用户目录下的store目录&#xff1a; store目录下的文件如上所示&#xff0c;分别有&#xff1a;checkpo…

[附源码]计算机毕业设计JAVA医院床位管理系统

[附源码]计算机毕业设计JAVA医院床位管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybati…

Halo搭建个人博客网站

Halo搭建个人博客网站 一、docker部署Halo 目前测试了两种方法安装Halo&#xff0c;第一种是使用Jar包安装:提供JAR包资源&#xff0c;不过因为使用jar包部署需要Java11才可以&#xff0c;我本机使用的是Java8&#xff0c;所以暂时不做调整。第二种是通过docker安装。 1.1 启…

项目实例:H3C端口镜像 (镜像单目的端口 镜像多目的端口)

一、项目实例 某局业务系统三级等保项目&#xff1a;配置只列出端口镜像部分&#xff0c;其他部分及设备&#xff08;略&#xff09; 1.1 边界部署两台防火墙做HA高可用 1.2 核心使用两台H3C交换机做堆叠&#xff0c;上联线路分别连接防火墙&#xff08;主&#xff09;、防火…

【Python自然语言处理】隐马尔可夫模型中维特比(Viterbi)算法解决商务选择问题实战(附源码 超详细必看)

需要源码请点赞关注收藏后评论区留言私信~~~ 一、统计分词 统计分词基本逻辑是把每个词语看做由单字组成&#xff0c;利用统计学原理计算连接字在不同文本中出现的次数&#xff0c;以此判断相连字属于特定词语的概率。 二、隐马尔可夫模型 当一个随机过程在给定现在状态及所…

计算机组成详解(运算器、控制器、存储器、I/O部件)

文章目录1 概述1.1 计算机组成图2 三大部件2.1 中央处理器 CPU运算器 ALU控制器 CU2.2 内存储器2.3 输入输出设备3 扩展3.1 计算机系统结构图1 概述 1.1 计算机组成图 2 三大部件 2.1 中央处理器 CPU 运算器 ALU 运算器 ALU&#xff1a;Arithmetic Logic Unit&#xff0c;算…