布隆过滤器相关知识

最近看流式系统的时候有提到Exactly-Once 策略 可以使用布隆过滤器(Bloom Filter) 优化, 所以今天来整理一下与其相关的知识 (非科班, 底子比较薄)。

应用原理:

  • Bloom Filter can return false positives but never false negatives.
  • 布隆过滤器能判断数据是否一定不存在, 而无法判断数据是否一定存在。
  • 因此它可以用于对数据进行查重, 从而保证 Exactly-Once 的策略

什么是布隆过滤器?

  • 他它本身是一个很长的二进制向量(0, 1), 假设以下为一个长度为16的布隆过滤器, 默认值为0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
坐标 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  • 假设添加了一条数据,其Hash散列得出的结果分别为 4,7,12, 如下所示:
0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0
坐标 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  • 添加的数据占据了4, 7, 12 这三个格子, 但布隆过滤器本身没有存放完整的数据, 只是运用一系列随机随机映射函数算出位置, 然后填充二进制向量。
  • 假设此时又来了一条数据, 要判断该数据是否重复, 只需要将该数据进行哈希散列, 查看该数据要占据哪些格子, 只要有一个格子的值不为1, 那么就代表这个数字不在其中。
  • 但如果该条数据的哈希散列值对应的格子的值都为1, 不一定代表给定的数据一定重复, 可能其他数据经过该散列函数算出来的结果也是相同的。(不过概率非常小) [不同对象的哈希取模可能是相等的]

优缺点

  • 优点: 由于存放的不是完整的数据, 所以占用的内存很少, 而且新增, 查询速度够快
  • 缺点:
    • 随着数据的增加, 误判率随之增加
    • 无法做到删除数据(牵一发而动全身, 会影响其他存储于该格子的数据)
    • 只能判断数据是否一定不存在, 而无法判断数据是否一定存在。

数据查重使用策略

  • 只要布隆过滤器任务数据不存在, 就可以执行插入。
  • 当布隆过滤器任务数据重复时, 统计可能重复的数据。
  • 布隆过滤器的误判率(通过迭代 + 极限计算可得):
    \[
    f \approx (1 - e^\frac{-nk}{m})^k
    \]
    m: 二进制向量的大小 (bit)

    k: 为hash运算的数量

    n: 加入其中的key的数量

  • 由于误判率可以计算且较小, 只要对可能重复的数据再重复进行过滤就可以将误判的数据逐渐剔除。
  • 这些数据只要有一次被判定为非重复数据, 那么它们就不是重复数据。

通过Google开源的guava实现布隆过滤器

  • Guava 是Google 开源的 常用方法 的 java语言工具包
  • 通过maven导入Guava坐标:
    <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>28.0-jre</version>
    </dependency>
  • 写代码执行测试
    package com.ronnie.bloom;
    
    import com.google.common.hash.BloomFilter;
    import com.google.common.hash.Funnels;
    
    public class BloomDemo {
    
        // 预计要插入的数据
        private static int size = 1000000;
    
        // 预估的误判率
        private static double falseProbability = 0.01;
    
        private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size, falseProbability);
    
        public static void main(String[] args) {
            // 插入数据
            for (int i = 0; i < size; i++){
                bloomFilter.put(i);
            }
            int count = 0;
            for (int i = size; i < size * 2; i++){
                if (bloomFilter.mightContain(i)){
                    count++;
                    System.out.println(i + "被误判了");
                }
            }
    
            System.out.println("总共误判了 " + count + " 个数");
        }
    }

    结果输出:

    1999501被误判了
    1999567被误判了
    1999640被误判了
    1999697被误判了
    1999827被误判了
    1999942被误判了
    总共误判了 10314 个数

    \[
    \frac{10314}{1000000}\approx 0.01
    \]

原文地址:https://www.cnblogs.com/ronnieyuan/p/11700749.html

时间: 2024-10-27 16:42:39

布隆过滤器相关知识的相关文章

Mina SSL Filter安全加密过滤器相关知识介绍

原文地址:Mina SSLFilter(Apahce Mina user guide Chapter11 SSL Filter) SslFilter过滤器是负责管理数据的加密和解密通过安全连接.每当你需要建立一个安全连接,或将现有的连接使它安全,你必须添加SslFilter过滤器链. 任何会话可以修改它的信息过滤器链,它允许使用协议像startTLS打开连接. 请注意,虽然这个名字包括SSL,SslFilter支持TLS.实际上,TLS已经支持取代SSL,但是由于历史原因,SSL仍然广泛使用.

[转载] 布隆过滤器(Bloom Filter)详解

转载自http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html   布隆过滤器[1](Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的.它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元素是否在一个集合中.它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率(假正例False positives,即Bloom Filter报告某一

布隆过滤器(Bloom Filter)详解

布隆过滤器(Bloom Filter)详解 2012-07-13 18:35 by Haippy, 29358 阅读, 6 评论, 收藏, 编辑   布隆过滤器[1](Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的.它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元素是否在一个集合中.它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率(假正例False positives,即Bloom Fi

【分享】布隆过滤器

  布隆过滤器[1](Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的.它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元素是否在一个集合中.它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率(假正例False positives,即Bloom Filter报告某一元素存在于某集合中,但是实际上该元素并不在集合中)和删除困难,但是没有识别错误的情形(即假反例False negatives,如果

算法&lt;初级&gt; - 第三章 布隆过滤器、一致性哈希等相关问题

算法第三章 布隆过滤器 海量数据管理,在哈希表上再压缩数据,但会存在较低的失误率 失误类型:宁可错杀三千不可错放一个,非存储数据小概率判断为存储数据 bit位数组存储:eg. int数组每位存储0~31位bit数组 思想:准备k个哈希函数,哈希值取模bit数组大小m,每个键经过记录得到k个哈希值范围[0,m-1],将bit数组k个哈希值的对应位置1.查表时,若是查询键中非全部哈希置位为1,则未被记录. 若是k个值有重复,则仍然置1,多余的不变 所有键共用一个bit数组 在bit数组映射整型数组的

布隆过滤器(Bloom Filter)的原理和实现

什么情况下需要布隆过滤器? 先来看几个比较常见的例子 字处理软件中,需要检查一个英语单词是否拼写正确 在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上 在网络爬虫里,一个网址是否被访问过 yahoo, gmail等邮箱垃圾邮件过滤功能 这几个例子有一个共同的特点: 如何判断一个元素是否存在一个集合中? 常规思路 数组 链表 树.平衡二叉树.Trie Map (红黑树) 哈希表 虽然上面描述的这几种数据结构配合常见的排序.二分搜索可以快速高效的处理绝大部分判断元素是否存在集合中的需求.但是当集合里

网络爬虫:URL去重策略之布隆过滤器(BloomFilter)的使用

前言: 最近被网络爬虫中的去重策略所困扰.使用一些其他的"理想"的去重策略,不过在运行过程中总是会不太听话.不过当我发现了BloomFilter这个东西的时候,的确,这里是我目前找到的最靠谱的一种方法. 如果,你说URL去重嘛,有什么难的.那么你可以看完下面的一些问题再说这句话. 关于BloomFilter: Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员.如果检测

hbase中的位图索引--布隆过滤器

在hbase中,读业务是非常频繁的.很多操作都是客户端根据meta表定位到具体的regionserver然后再查询region中的具体的数据. 但是现在问题来了,一个region由一个memstore以及多个filestore组成,memstore类似缓存在服务器内存中,可以提高插入的效率,当memstore达到一定大小(由hbase.hregion.memstore.flush.size设置)或者说用户手动flush之后,就会固化存储在hdfs之类的磁盘系统上.也就是说一个region可以对应

海量数据处理利器之布隆过滤器

看见了海量数据去重,找到停留时间最长的IP等问题,有博友提到了Bloom Filter,我就查了查,不过首先想到的是大叔,下面就先看看大叔的风采. 一.布隆过滤器概念引入 (Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的.它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元素是否在一个集合中.它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率(假正例False positives,即Bloom