布隆过滤器(BloomFilter)
一、简述
有时候我们需要 判断一个元素是否在一个集合中 。最直接的方法就是将集合中的元素存在计算机中,遇到一个新元素时,将它和集合中的元素直接比较即可。一般来讲,计算机中的集合是用哈希表来存储的。它的好处是快速准确,缺点是耗费存储空间。其根本原因是哈希表方法需要把实实在在的具有特定长度(每个 Email 地址对应成一个 8 字节的信息指纹)的元素的信息指纹存储在内存或硬盘中的哈希表中。比如每存储一亿个 Email 地址,需要 0.8G 大小的数字指纹存储空间,考虑到哈希表的存储空间利用率一般只有一半,所以需要 1.6G 的存储空间。如果存储几十亿上百亿的 Email 地址,那就需要百亿字节的内存存储空间。
布隆过滤器 主要就是用于解决:快速判断一个元素是否在一个集合中,优势是只需要 占用很小的内存空间以及有着高效的查询效率 ,缺点是 不能从布隆过滤器中删除元素和有一定的误报率
二、原理
利用一个 很长的二进制向量 和一系列的随机映射函数 来实现。
- 首先需要初始化一个二进制的数组,长度设为 L ,同时初始值全为 0。
- 当写入一个 A1=1000 的数据时,需要进行 H 次 hash 函数的运算;与 HashMap 有点类似,通过算出 hashcode 与 L 取模后定位到 0、2 处,将该处的值设为 1。
- A2=2000 也是同理计算后将 4、7 位置设为 1。
- 当有一个 B1=1000 需要判断是否存在时,也是做两次 hash 运算,定位到 0、2 处,此时他们的值都为 1,所以认为 B1=1000 存在于集合中。
- 当有一个 B2=3000 时,也是同理。第一次 Hash 定位到 index=4 时,数组中的值为 1,所以再进行第二次 hash 运算,结果定位到 index=5 的值为 0,所以认为 B2=3000 不存在于集合中。
三、特点
- 只要返回数据不存在,则肯定不存在。
- 返回数据存在,只能是大概率存在。
- 不能清除其中的数据
- 误报率和布隆过滤器的位数是负相关的
- 映射函数函数多浪费算力,一般取 0.7* 布隆位数 / 元素个数
四、设计方法
- 决定元素个数 n 和期望误差 p
- 布隆位数为 -n*ln(p) / ln(2)^2
- 哈希函数个数为 0.7*m/n
- 为了保证低于期望误差,可以适当增加布隆位数