首页 > 其他分享 >完全解读布隆过滤器

完全解读布隆过滤器

时间:2025-01-18 15:59:41浏览次数:3  
标签:元素 碰撞 布隆 cachePenetrationBloomFilter 解读 过滤器 public



布隆过滤器(Bloom Filter)是 1970 年由布隆提出的,是一种非常节省空间的概率数据结构,运行速度快,占用内存小。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。主要用于判断一个元素是否在一个集合中。主要是解决大规模数据下不需要精确过滤的场景,如检查垃圾邮件地址,爬虫URL地址去重,解决缓存穿透问题等。

优点

●存储空间和插入 / 查询时间都是常数O(k)
●支持海量数据场景下高效率判断元素是否存在
●存储空间小,不存储数据本身,而是存储hash结果取模运算后的位标记

缺点

●无法删除,因为可能多个元素通过哈希后,可能会产生hash碰撞,映射到布隆过滤器的同一个位置。删除该位置后,可能影响其他元素
●误判,由于存在hash碰撞,不同的元素经过哈希后可能映射到同一个位置,一旦产生碰撞,会被误判存在
●碰撞概率,让随着元素越来越大,在容量限制下,布隆过滤器被使用的位置就会越来越多,误判的几率也会越来越大

特点

根据布隆过滤器的特点可以知道

●判断如果某个元素存在,由于存在误判,这个元素不一定是存在的
●判断如果某个元素不存在,那这个元素一定不存在

原理

结构


布隆过滤器底层就是一个二进制的位数组,在初始状态,所有位置的位都是0

添加

●使用哈希函数对元素进行哈希计算得到索引值,将索引值对应的数组下标所在的值设置为1
●如果是多个哈希函数则进行上述同样的操作

查询

●对要查询的元素同样使用哈希函数进行计算,如果存在多个哈希函数则得到多个索引值
●判断这些索引值对应的数组下标的值是否都为1,如果是,则判断这个元素为存在。如果这些下标的值只要有一个是0,那么判断这个元素为不存在

流程图

容量估算

当我们知道了布隆过滤器的原理后,还剩下个问题,就是要估算出布隆过滤器所需要的容量,以便于配置服务器的容量

布隆过滤器的容量是和产生的碰撞概率有关的,通过布隆过滤器的原理能知道,容量和碰撞概率的关系就是相斥的

要想碰撞概率小,容量肯定就要大。

要想容量小,碰撞概率肯定就要大

公式

那么具体要如何估算呢,我们可以根据公式要进行计算:

m可能算到小数,那就向上取整

参数解释

  • n 元素的样本量
  • p 碰撞率
  • m 布隆过滤器占用比特数

进行计算

以用户注册业务为例,我们需要计算 n,也就是用户量需要多少

2023年末2024年初,常住人口140967万人,这里我们直接取整为14亿,假设这14亿人所有人都是大麦网的用户,用这个数字作为布隆过滤器的容量来说,以目前国内的用户增长量来说,五年内绝对是没有任何问题的

至于碰撞率 p 我们取一个比较精确的值,0.2%

n = 14亿p = 0.2% 带入公式中,计算出

这时 m 的单位是bit,如果换成GB单位, 则

依赖

<dependency>
    <groupId>com.example</groupId>
    <artifactId>damai-bloom-filter-framework</artifactId>
    <version>${revision}</version>
</dependency>

结构

属性配置
@Data
@ConfigurationProperties(prefix = BloomFilterProperties.PREFIX)
public class BloomFilterProperties {

    public static final String PREFIX = "bloom-filter";
    /**
    * 布隆过滤器名字
    */
    private String name;
    /**
    * 布隆过滤器的容量
    */
    private Long expectedInsertions = 20000L;
    /**
    * 布隆过滤器碰撞率
    */
    private Double falseProbability = 0.01D;
}
自动装配
@EnableConfigurationProperties(BloomFilterProperties.class)
public class BloomFilterAutoConfiguration {
    
    /**
     * 布隆过滤器
     */
    @Bean
    public BloomFilterHandler rBloomFilterUtil(RedissonClient redissonClient, BloomFilterProperties bloomFilterProperties) {
        return new BloomFilterHandler(redissonClient, bloomFilterProperties);
    }
}
布隆过滤器操作
public class BloomFilterHandler {
    
    private final RBloomFilter<String> cachePenetrationBloomFilter;
    
    public BloomFilterHandler(RedissonClient redissonClient, BloomFilterProperties bloomFilterProperties){
        RBloomFilter<String> cachePenetrationBloomFilter = redissonClient.getBloomFilter(bloomFilterProperties.getName());
        cachePenetrationBloomFilter.tryInit(bloomFilterProperties.getExpectedInsertions(), bloomFilterProperties.getFalseProbability());
        this.cachePenetrationBloomFilter = cachePenetrationBloomFilter;
    }
    
    public boolean add(String data) {
        return cachePenetrationBloomFilter.add(data);
    }
    
    public boolean contains(String data) {
        return cachePenetrationBloomFilter.contains(data);
    }
    
    public long getExpectedInsertions() {
        return cachePenetrationBloomFilter.getExpectedInsertions();
    }
    
    public double getFalseProbability() {
        return cachePenetrationBloomFilter.getFalseProbability();
    }
    
    public long getSize() {
        return cachePenetrationBloomFilter.getSize();
    }
    
    public int getHashIterations() {
        return cachePenetrationBloomFilter.getHashIterations();
    }
    
    public long count() {
        return cachePenetrationBloomFilter.count();
    }
}

使用

在用户注册的流程中,使用了布隆过滤器判断用户手机号是否存在,下面来分析使用过程

redis配置

spring:
  data:
    redis:
      database: 0
      host: 127.0.0.1
      port: 6379
      password: 123456
      timeout: 3000

布隆过滤器配置

bloom-filter:
  name: user-register-bloom-filter
  expectedInsertions: 1000
  falseProbability: 0.01

 service.UserService

public void doExist(String mobile){
    boolean contains = bloomFilterHandler.contains(mobile);
    if (contains) {
        LambdaQueryWrapper<UserMobile> queryWrapper = Wrappers.lambdaQuery(UserMobile.class)
                .eq(UserMobile::getMobile, mobile);
        UserMobile userMobile = userMobileMapper.selectOne(queryWrapper);
        if (Objects.nonNull(userMobile)) {
            throw new DaMaiFrameException(BaseCode.USER_EXIST);
        }
    }
}
  1. 判断用户手机号在布隆过滤器中是否存在
  2. 如果判断存在的话,由于布隆过滤器有碰撞率,则需要在数据库中再次判断

标签:元素,碰撞,布隆,cachePenetrationBloomFilter,解读,过滤器,public
From: https://blog.csdn.net/ksidgx/article/details/145228533

相关文章

  • 科普文:算法和数据结构系列【高效的字符串检索结构:字典树Trie树原理、应用及其java示例
    概叙科普文:算法和数据结构系列【算法和数据结构概叙】-CSDN博客科普文:算法和数据结构系列【非线性数据结构:树Tree和堆Heap的原理、应用、以及java实现】-CSDN博客科普文:算法和数据结构系列【树:4叉树、N叉树】_动态维护四叉树-CSDN博客科普文:算法和数据结构系列【二叉树总结......
  • 深入解读:华为集成服务交付ISD业务变革总体方案
            华为集成服务交付(ISD)业务变革总体方案旨在通过转变服务交付视角和业务运作模式,以适应运营商转型的需求。变革的核心在于从单纯的设备供应商转变为运营商视角的设备和服务提供商,承担更多职责和角色。        该方案提出了“四位一体”的变革框架,包括......
  • GaussDB技术解读——GaussDB架构介绍之数据持久化存取层(DataNode)关键技术方案
    数据持久化存取层(DataNode)关键技术方案Datanode节点主要负责数据的持久化和快速写入、读取。数据持久化采用物理日志wal,事务提交wal刷盘,对外提供逻辑日志功能,反解析物理日志为SQL逻辑日志。图1datanode数据持久化Astore:存储格式为追加写优化设计,其多版本元组采用新、老版......
  • GaussDB技术解读——GaussDB架构介绍之全局事务管理层(GTM)关键技术方案
    GTM仅处理全局时间戳请求,64位CSN递增,几乎都是CPU++和消息收发操作。不是每次都写ETCD,而是采用定期持久化到ETCD里,每次写ETCD的CSN要加上一个backup_step(100w),一旦GTM故障,CSN从ETCD读取出来的值保证单调递增。当前GTM只完成CSN++,预估可以支持200M/s请求。GTM处理......
  • GaussDB技术解读——GaussDB架构介绍之集群管理层(CM)关键技术方案
    GaussDBKernelV5集群管理层关键模块如下。图4集群管理层组件设计图CM组件提供了四种服务CMAgent,CMServer,OMMonitor,cm_ctl,与各类实例服务组件(CN,DN,GTM等)一起构成了整个数据库集群系统。cm_ctl通过命令行执行集群的启动、停止、状态查询、主备倒换、备机重......
  • GaussDB技术解读——GaussDB架构介绍之OM运维管理关键技术方案
    ​GaussDBKernelV5OM运维管理关键模块如下。OM运维主要功能有:安装升级节点替换扩容、缩容自动告警巡检备份恢复、容灾日志分析系统在华为云的部署模式下,OM相关组件部署示意图如下:图7华为云OM运维管理用户登录华为云Console,访问GaussDBKernelV5的管控页面,输入......
  • Spark 源码分析(二) SparkRpc中Rpc架构解读 (正在更新 MessageLoop部分~)
    接上一篇SparkRpc框架阐述目录2、Dispatcher调度器具体实现(1)、Dispatcher构造体(2)、方法1 registerRpcEndpoint简单说说 sharedLoop和 IsolatedRpcEndpoint的区别1、IsolatedRpcEndpoint2、sharedLoop(3)方法2 getRpcEndpointRef(4)方法3 removeRpcEndpo......
  • 费曼学习法解读:自然语言处理
    自然语言处理呀,就好比你和一个特别聪明的小助手在交流。 你平时说话、写字用的语言就是自然语言,比如中文、英文这些。自然语言处理呢,就是让电脑能理解我们人类的这些自然语言,就像那个小助手能听懂你说的话一样。 比如说,你用语音助手问“今天天气怎么样?”,这个语音助手就得......
  • 费曼学习法解读:什么是机器学习
    机器学习呢,就像是一个学生在不断学习进步。 想象一下有个小朋友,一开始他什么都不会,但是他通过不断地看例子、做练习,慢慢地就学会了很多东西。机器学习也是这样,电脑程序一开始也不知道怎么完成某些任务,但是它通过大量的数据来学习。 比如说,识别图片里是猫还是狗。一开始电......
  • 费曼学习法解读:什么是UI
    UI呢,就像是一个房子的装修。 假如你有一个房子,UI就是把这个房子装修得漂漂亮亮、让人看着舒服又好用的东西。 比如说,你打开一个手机软件,那个软件的界面就是UI。界面上的各种图标啦、颜色啦、字体啦,这些组合在一起,让你一看就知道怎么用这个软件。 如果UI做得好,就像......