redis添加布隆过滤器插件
概念
布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。
redis在4.0版本以后可通过插件的形式添加布隆过滤器
编译安装
到redis安装目录创建module目录
cd /opt/server/redis
mkdir module && cd module
git clone代码
yum -y install git
git clone https://github.com/RedisLabsModules/redisbloom.git
编译
cd redisbloom
make
编译后得到动态库redisbloom.so
Redis引入该模块
- (1)在redis.conf配置文件里加入如下引入配置
loadmodule ../module/redisbloom/redisbloom.so
- (2)redis集群每个配置文件都需要加入这一行
- (3)添加完配置后重启redis
布隆过滤器基本使用
redis 布隆过滤器主要就两个命令:
bf.add
添加元素到布隆过滤器中:bf.add urls https://jaychen.cc
。bf.exists
判断某个元素是否在过滤器中:bf.exists urls https://jaychen.cc
。
上面说过布隆过滤器存在误判的情况,在 redis 中有两个值决定布隆过滤器的准确率:
error_rate
:允许布隆过滤器的错误率,这个值越低过滤器的位数组的大小越大,占用空间也就越大。initial_size
:布隆过滤器可以储存的元素个数,当实际存储的元素个数超过这个值之后,过滤器的准确率会下降。
redis 中有一个命令可以来设置这两个值:
bf.reserve urls 0.01 100
三个参数的含义:
-
第一个值是过滤器的名字。
-
第二个值为
error_rate
的值。 -
第三个值为
initial_size
的值。如果不使用 bf.reserve,默认的error_rate是 0.01,默认的initial_size是 100。
127.0.0.1:6379> bf.add user:bf 1001
(integer) 1
127.0.0.1:6379> bf.add user:bf 1002
(integer) 1
127.0.0.1:6379> bf.add user:bf 1003
(integer) 1
127.0.0.1:6379> bf.exists user:bf 1001
(integer) 1
127.0.0.1:6379> bf.exists user:bf 1002
(integer) 1
127.0.0.1:6379> bf.exists user:bf 1003
(integer) 1
127.0.0.1:6379> bf.exists user:bf 1004
(integer) 0
127.0.0.1:6379> bf.madd user:bf 1004 1005 1006
1) (integer) 1
2) (integer) 1
3) (integer) 1
127.0.0.1:6379> bf.mexists user:bf 1004 1005 1006 1007
1) (integer) 1
2) (integer) 1
3) (integer) 1
4) (integer) 0
127.0.0.1:6379>
注意事项
布隆过滤器的initial_size估计的过大,会浪费存储空间,估计的过小,就会影响准确率,用户在使用之前一定要尽可能地精确估计好元素数量,还需要加上一定的冗余空间以避免实际元素可能会意外高出估计值很多。
布隆过滤器的error_rate越小,需要的存储空间就越大,对于不需要过于精确的场合,error_rate设置稍大一点也无伤大雅。比如在新闻去重上而言,误判率高一点只会让小部分文章不能让合适的人看到,文章的整体阅读量不会因为这点误判率就带来巨大的改变。
布隆过滤器的其它应用
在爬虫系统中,我们需要对 URL 进行去重,已经爬过的网页就可以不用爬了。但是 URL 太多了,几千万几个亿,如果用一个集合装下这些 URL 地址那是非常浪费空间的。这时候就可以考虑使用布隆过滤器。它可以大幅降低去重存储消耗,只不过也会使得爬虫系统错过少量的页面。
布隆过滤器在 NoSQL 数据库领域使用非常广泛,我们平时用到的 HBase、Cassandra 还有 LevelDB、RocksDB 内部都有布隆过滤器结构,布隆过滤器可以显著降低数据库的 IO 请求数量。当用户来查询某个 row 时,可以先通过内存中的布隆过滤器过滤掉大量不存在的 row 请求,然后再去磁盘进行查询。
邮箱系统的垃圾邮件过滤功能也普遍用到了布隆过滤器,因为用了这个过滤器,所以平时也会遇到某些正常的邮件被放进了垃圾邮件目录中,这个就是误判所致,概率很低。