- 引出布隆过滤器
- 布隆过滤器与原理
- 布隆过滤器误差率
- 本地布隆过滤器
- Redis单机布隆过滤器
- Redis分布式布隆过滤器
1、引出布隆过滤器
- 情景应用
现有50亿个电话号码,现有10万个电话号码,要快速准确判断这些号码是否已经存在?
- 1.通过数据库查询:实现快速有点难
- 2.数据预存放在集合中:50亿*8=40GB(资源浪费)
- 3.hyperloglog:准确有点难
类似问题有:
- 垃圾邮件过滤
- 文字处理软件
- 网络爬虫重复url检测
- Hbase行过滤
2、布隆过滤器原理
1970年波顿布隆提出,用很小的空间,解决上述问题。
实现原理:一个很长的二进制向量(位图bitmap)和若干个哈希函数。
上述n(50亿)个八位数字分别经过k个哈希函数,分别将取得的哈希值和m取模,计算如果在二进制中有则制为1,否则为0。
2.1 布隆过滤器构建
参数:m个二进制向量,n(50亿个手机号码)个预备数据,k(8位)个哈希函数
构建布隆过滤器:n个预备数据走一边上面过程
- 判断元素存在:走一遍上面过程:如果都是1,则在表明表明存在,反之不存在。
类似应用:
面试题:1000瓶水其中有一瓶水有毒,有10只老鼠并且只要老鼠喝了有毒的水必死。请问怎样通过一次实验找出有毒的那瓶水。
2.2 误差率
-
肯定存在误差:恰好都命中了
-
可能出现对的数据肯定都是对的,但是错的数据也有可能当成对的
分析:因为哈希函数是不变的,因为已经预写过一遍,所以对的数据肯定是对的;但是错的数据也有可能落在对的数据上,所以会差生误差。(原因:哈希函数自变量x范围无穷大,而取值范围有限)
-
直观因素:m/n的比率,hash函数的个数
-
这里当m/n越大时,误差率越低,(位图)占用空间内存也越大;
-
当k很小(为1)误差率很高,只有一个哈希函数不可靠,但当k很大时,误差率也会很高,位图全被描黑,查询的url全都显示有。
(位图大小) m和误差关系
k和误差关系
- 布隆过滤器的应用 Hadoop、Redis缓存穿透可以采用布隆过滤器。
3.本地布隆过滤器
- 现有库 :guava
- 使用方法:
- 缺点
(1) 容量受限制
(2) 多个应用存在多个布隆过滤器,构建同步复杂
4.基于Redis布隆过滤器
- 基于位图实现
- 实现方法
定义布隆过滤器构造参数:m、n、k、误差概率
定义布隆过滤器操作函数:add和contain
封装Redis位图操作
开发测试样例
基于Redis单机实现存在的问题
- 速度慢:毕本地幔,输在网络
解决:单独部署,应用同机房甚至机架部署
- 容量受限:Redis最大字符串为512MB、Redis单机容量。
解决:基于Redis Cluster实现
5.分布式布隆过滤器
附录
缓存穿透(穿透):布隆过滤器,返回null值
缓存击穿(量太大,缓存过期):设置热点数据不过期,加互斥锁
缓存雪崩(缓存集中过期失效停机断网):异地多活,限流降级,数据预热(随机设置过期时间)