一、布隆过滤器
1. 定义
它是一种space efficient的概率型数据结构,用于判断一个元素是否在集合中。主要用来去重,且空间占用少
2. 特点
- 具有去重功能,并且空间相比较其他数据结构,占用很少
- 当布隆过滤器说某个值存在时,这个值可能不存在;当它说不存在时,那就肯定不存在
- 布隆过滤器可以插入元素,但不可以删除已有元素.
- 只要参数调整合适(需要添加的总元素数量和误差率),误差率可以控制
3. 用途
- 新闻推荐系统(用户看过的新闻不推荐)
- 爬虫url去重
- 垃圾邮件过滤
- 其他等等
4. 算法原理
每个布隆过滤器对应到 Redis 的数据结构里面就是一个大型的位数组和几个不一样的无偏 hash 函数。所谓无偏就是能够把元素的 hash 值算得比较均匀。
(1) add
向布隆过滤器中添加 key 时,会使用多个 hash 函数对 key 进行 hash 算得一个整数索引值然后对位数组长度进行取模运算得到一个位置,每个 hash 函数都会算得一个不同的位置。再把位数组的这几个位置都置为 1 就完成了 add 操作。
(2) query
向布隆过滤器询问 key 是否存在时,跟 add 一样,也会把 hash 的几个位置都算出来,看看位数组中这几个位置是否都位 1,只要有一个位为 0,那么说明布隆过滤器中这个key 不存在。如果都是 1,这并不能说明这个 key 就一定存在,只是极有可能存在,因为这些位被置为 1 可能是因为其它的 key 存在所致。
(3) 时间复杂度
add和query的时间复杂度都为O(k),k为hash函数的个数
(4) 图解
5. 空间占用和误判率估计
(1) 空间暂用率估计
//预计元素的数量 n;第二个是错误率 f;位数组的长度 l,也就是需要的存储空间大小 (bit);hash 函数的最佳数量 k:
k=0.7*(l/n) # 约等于
f=0.6185^(l/n) # ^ 表示次方计算,也就是 math.pow
(2) 误判率估计
当实际元素超出预计元素时,错误率会有多大变化,它会急剧上升么,还是平缓地上升?
这就需要另外一个公式,引入参数 t 表示实际元素和预计元素的倍数 t:
f=(1-0.5^t)^k # 极限近似,k 是 hash 函数的最佳数量
二、Redis布隆过滤器
redisbloom官网地址
redisbloom命令使用方法
1. redisbloom安装
(1) 源码安装
shell> git clone https://github.com/RedisBloom/RedisBloom.git
shell> cd RedisBloom/
shell> make
//启动redis
shell> redis-server ../../redis.conf --loadmodule ./redisbloom.so
(2) 利用docker
//安装docker(ubuntu 18.04)
shell> sudo apt install docker.io
shell> docker --version
//带redisbloom插件启动redis
shell> docker run -p 6379:6379 --name redis-redisbloom redislabs/rebloom:latest
//当容器存在且停止时,再次启动redis镜像容器
shell> docker start redis-redisbloom