面试官问:什么是布隆过滤器?
布隆过滤器
布隆过滤器是一种由位数组和多个哈希函数组成概率数据结构,返回两种结果 可能存在 和 一定不存在。
布隆过滤器里的一个元素由多个状态值共同确定。位数组存储状态值,哈希函数计算状态值的位置。
根据它的算法结构,有如下特征:
- 使用有限位数组表示大于它长度的元素数量,因为一个位的状态值可以同时标识多个元素。
- 不能删除元素。因为一个位的状态值可能同时标识着多个元素。
- 添加元素永远不会失败。只是随着添加元素增多,误判率会上升。
- 如果判断元素不存在,那么它一定不存在。
比如下面,X,Y,Z 分别由 3个状态值共同确定元素是否存在,状态值的位置通过3个哈希函数分别计算。
数学关系
误判概率
关于误判概率,因为每个位的状态值可能同时标识多个元素,所以它存在一定的误判概率。如果位数组满,当判断元素是否存在时,它会始终返回true
,对于不存在的元素来说,它的误判率就是100%。
那么,误判概率和哪些因素有关,已添加元素的数量,布隆过滤器长度(位数组大小),哈希函数数量。
根据维基百科推理误判概率 PfpPfp 有如下关系:
Pfp=(1−[1−1m]kn)k≈(1−e−knm)kPfp=(1−[1−1m]kn)k≈(1−e−knm)k
- mm 是位数组的大小;
- nn 是已经添加元素的数量;
- kk 是哈希函数数量;
- ee 数学常数,约等于2.718281828。
由此可以得到,当添加元素数量为0时,误报率为0;当位数组全都为1时,误报率为100%。
不同数量哈希函数下,PfpPfp 和 nn 的关系如下图:
根据误判概率公式可以做一些事
- 估算最佳布隆过滤器长度。
- 估算最佳哈希函数数量。
最佳布隆过滤器长度
当 nn 添加元素和 PfpPfp误报概率确定时,mm 等于:
m=−nlnPfp(ln2)2≈−1.44⋅nlog2Pfpm=−nlnPfp(ln2)2≈−1.44⋅nlog2Pfp
最佳哈希函数数量
当 nn 和 PfpPfp 确定时,kk 等于:
k=−lnPfpln2=−log2Pfpk=−lnPfpln2=−log2Pfp
当 nn 和 mm 确定时,kk 等于:
k=mnln2k=mnln2
实现布隆过滤器
使用布隆过滤器前,我们一般会评估两个因素。
- 预期添加元素的最大数量。
- 业务对错误的容忍程度。比如1000个允许错一个,那么误判概率应该在千分之一内。
很多布隆过滤工具都提供了预期添加数量和误判概率配置参数,它们会根据配置的参数计算出最佳的长度和哈希函数数量。
Java中有一些不错的布隆过滤工具包。
Guava
中BloomFilter
。redisson
中RedissonBloomFilter
可以redis 中使用。
看下 Guava
中 BloomFilter
的简单实现,创建前先计算出位数组长度和哈希函数数量。
static <T> BloomFilter<T> create(Funnel<? super T> funnel, long expectedInsertions, double fpp, Strategy strategy) {/*** expectedInsertions:预期添加数量* fpp:误判概率*/long numBits = optimalNumOfBits(expectedInsertions, fpp);int numHashFunctions = optimalNumOfHashFunctions(expectedInsertions, numBits);try {return new BloomFilter<T>(new BitArray(numBits), numHashFunctions, funnel, strategy);} catch (IllegalArgumentException e) {throw new IllegalArgumentException("Could not create BloomFilter of " + numBits + " bits", e);}}
根据最佳布隆过滤器长度公式,计算最佳位数组长度。
static long optimalNumOfBits(long n, double p) {if (p == 0) {p = Double.MIN_VALUE;}return (long) (-n * Math.log(p) / (Math.log(2) * Math.log(2)));}
根据最佳哈希函数数量公式,计算最佳哈希函数数量。
static int optimalNumOfHashFunctions(long n, long m) {return Math.max(1, (int) Math.round((double) m / n * Math.log(2)));}
在redisson
中 RedissonBloomFilter
计算方法也是一致。
private int optimalNumOfHashFunctions(long n, long m) {return Math.max(1, (int) Math.round((double) m / n * Math.log(2)));}private long optimalNumOfBits(long n, double p) {if (p == 0) {p = Double.MIN_VALUE;}return (long) (-n * Math.log(p) / (Math.log(2) * Math.log(2)));}
内存占用
设想一个手机号去重场景,每个手机号占用22 Byte
,估算逻辑内存如下。
expected | HashSet | fpp=0.0001 | fpp=0.0000001 |
---|---|---|---|
100万 | 18.28MB | 2.29MB | 4MB |
1000万 | 182.82MB | 22.85MB | 40MB |
1亿 | 1.78G | 228.53MB | 400MB |
注:实际物理内存占用大于逻辑内存。
误判概率 pp 和已添加的元素 nn,位数组长度 mm,哈希函数数量 kk 关系如下:
应用场景
- 弱密码检测;
- 垃圾邮件地址过滤。
- 浏览器检测钓鱼网站;
- 缓存穿透。
弱密码检测
维护一个哈希过弱密码列表。当用户注册或更新密码时,使用布隆过滤器检查新密码,检测到提示用户。
垃圾邮件地址过滤
维护一个哈希过垃圾邮件地址列表。当用户接收邮件,使用布隆过滤器检测,检测到标识为垃圾邮件。
浏览器检测钓鱼网站
使用布隆过滤器来查找钓鱼网站数据库中是否存在某个网站的 URL。
缓存穿透
缓存穿透是指查询一个根本不存在的数据,缓存层和数据库都不会命中。当缓存未命中时,查询数据库
- 数据库不命中,空结果不会写回缓存并返回空结果。
- 数据库命中,查询结果写回缓存并返回结果。
一个典型的攻击,模拟大量请求查询不存在的数据,所有请求落到数据库,造成数据库宕机。
其中一种解决方案,将存在的缓存放入布隆过滤器,在请求前进行校验过滤。
小结
对于千万亿级别的数据来说,使用布隆过滤器具有一定优势,另外根据业务场景合理评估预期添加数量和误判概率是关键。
面试官问:什么是布隆过滤器?相关推荐
- 【200期】面试官问:Spring Security 和 Shiro 该如何选择?
点击上方"Java精选",选择"设为星标" 别问别人为什么,多问自己凭什么! 下方有惊喜,留言必回,有问必答! 每天 08:15 更新文章,每天进步一点点... ...
- 面试官问你想找什么工作_找工作时如何面试面试官
面试官问你想找什么工作 在技术面试中要问的十二个问题 (Twelve questions to ask at tech interviews) I've just come off six wee ...
- 面试官问:select......for update会锁表还是锁行?
欢迎关注方志朋的博客,回复"666"获面试宝典 select查询语句是不会加锁的,但是select .......for update除了有查询的作用外,还会加锁呢,而且它是悲观锁 ...
- 面试官问:数据库 delete 表数据,磁盘空间还是被一直占用,为什么?
以下文章来源方志朋的博客,回复"666"获面试宝典 最近有个上位机获取下位机上报数据的项目,由于上报频率比较频繁且数据量大,导致数据增长过快,磁盘占用多. 为了节约成本,定期进行数 ...
- 面试官问:Kafka 会不会丢消息?怎么处理的?
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! Kafka存在丢消息的问题,消息丢失会发生在Broker, ...
- 面试官问:Integer 如何实现节约内存和提升性能的?
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:Byte_Liu 来源:https://urlify.cn/ ...
- 面试官问我:一个 TCP 连接可以发多少个 HTTP 请求?我竟然回答不上来...
点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 作者 | 松若章 来源 | https://zhuanlan.zhihu.com/p/6142 ...
- 面试官问:请拿出一段体现你水平的代码,我该如何回答?
程序员面试,免不了被问代码问题.如果面试官问你,最能代表你的当下水平的代码是什么?你该怎么回答呢?知乎的几位作者给出了优秀答案. 每天下班前半小时都会运行这段. #include <stdlib ...
- 后处理程序文件大小的变量_【每日一题】(17题)面试官问:JS中事件流,事件处理程序,事件对象的理解?...
关注「松宝写代码」,精选好文,每日一题 作者:saucxs | songEagle 2020,实「鼠」不易 2021,「牛」转乾坤 风劲潮涌当扬帆,任重道远须奋蹄! 一.前言 2020.12.23 立 ...
- 当面试官问我ArrayList和LinkedList哪个更占空间时,我这么答让他眼前一亮
前言 今天介绍一下Java的两个集合类,ArrayList和LinkedList,这两个集合的知识点几乎可以说面试必问的. 对于这两个集合类,相信大家都不陌生,ArrayList可以说是日常开发中用的 ...
最新文章
- windows监控——再见zmq
- [转]SVN + CruiseControl.NET + NANT 自动编译提交的项目最小DEMO
- PHP对二维数组中的某个字段的值进行排序
- 电中在线计算机应用基础二考试题目及答案,最新电大2015计算机应用基础作业2 答案.doc...
- 今天预计有多少人买饭团?李彦宏说百度用PaddlePaddle给答案
- Luogu P2595 [ZJOI2009]多米诺骨牌 容斥,枚举,插头dp,轮廓线dp
- Deep Learning 学习笔记
- VESA编程——GUI离我们并不遥远
- android 重力模拟,android的模拟器怎样仿真重力感应器
- 【Numpy】1. n维数组,dtype,切片,索引
- 综合评价之熵值法+TOPSIS
- 百度富文本编辑器使用方法 html,配置使用百度提供的富文本编辑器ueditor(以项目实例图文步骤演示具体配置步骤)...
- Ceph 学习——OSD读写流程与源码分析(一)
- Typec转HDMI 4K30HZ扩展芯片方案CS5261和CS5266设计参数及电路对比
- 12306.cn网站挂了”好文章收藏,引发的技术架构问题讨论。
- 尚学堂就业怎么样?谈谈我在尚学堂的就业之路
- 良好的客户服务始于帮助中心
- 基于SSM的文书处理及档案管理系统 java毕业设计
- Ubuntu下无法安装R语言vcd包解决办法
- Python基础教程-菜鸟教程学习笔记1
热门文章
- antiddos翻译_AntiDDoS8000系列DDoS防御系统
- 仪表指针样式_Qt自定义Widget之仪表盘
- Pandas 操作 csv 文件
- c++17(18)-static_cast
- 当深度学习遇上图: 图神经网络的兴起!(文末送书)
- 【机器学习基础】超全汇总!机器学习常用术语词汇表(建议收藏)
- 干货!华为AutoML助力AI开发效率提升攻略
- 斯坦福CS229机器学习课程的数学基础(线性代数)翻译完成
- 极致流畅体验的密码:网易云信 QoS 策略介绍 | 体验共享技术专题
- 娱乐社交,玩票大的!网易云信“2021融合通信开发者大赛”正式收官!