赞
踩
redis+布隆过滤器思路图:https://kdocs.cn/l/sgVaSvSB3Z0s
①、原本有10亿个号码,现在又来了10万个号码,要快速准确判断这10万个号码是否在10亿个号码库中?
解决办法一:将10亿个号码存入数据库中,进行数据库查询,准确性有了,但是速度会比较慢。
解决办法二:将10亿号码放入内存中,比如Redis缓存中,这里我们算一下占用内存大小:10亿*8字节=8GB,通过内存查询,准确性和速度都有了,但是大约8gb的内存空间,挺浪费内存空间的。
②、接触过爬虫的,应该有这么一个需求,需要爬虫的网站千千万万,对于一个新的网站url,我们如何判断这个url我们是否已经爬过了?
解决办法还是上面的两种,很显然,都不太好。
③、同理还有垃圾邮箱的过滤。
那么对于类似这种,大数据量集合,如何准确快速的判断某个数据是否在大数据量集合中,并且不占用内存,布隆过滤器应运而生了。
布隆过滤器:一种数据结构,是由一串很长的二进制向量组成,可以将其看成一个二进制数组。既然是二进制,那么里面存放的不是0,就是1,但是初始默认值都是0。
1、布隆需要记录见过的数据,这里的记录需要通过hash函数对数据进行hash操作,得到数组下标并存储在BIT 数组里记为1。这样的记录一个数据只占用1BIT空间
2、判断是否存在时:给布隆过滤器一个数据,进行hash得到下标,从BIT数组里取数据如果是1 则说明数据存在,如果是0 说明不存在
hash算法存在碰撞的可能,所以不同的数据可能hash为一个下标数据,故为了提高精确度就需要 使用多个hash 算法标记一个数据,和增大BIT数组的大小
也是因为如此,布隆过滤器判断为【数据存在】 可能数据并不存在,但是如果判断为【数据不存在】那么数据就一定是不存在的。
布隆过滤器只能插入数据判断是否存在,不能删除,而且只能保证【不存在】判断绝对准确
以上不难看出如果给数组的每个BIT位上加一个计数器,插入的时候+1 删除的时候 –1 就可以实现删除。
但是加计数器的实现是有问题的:
由于hash碰撞问题,布隆过滤器不能准确判断数据是否存在,就不能随意删除。其次计数器的回绕问题也需要考虑。
优点:优点很明显,二进制组成的数组,占用内存极少,并且插入和查询速度都足够快。
缺点:随着数据的增加,误判率会增加;还有无法判断数据一定存在;另外还有一个重要缺点,无法删除数据。
- 地址:https://github.com/RedisBloom/RedisBloom
-
- 下载ZIP 文件,上传到linux
- RedisBloom-master.zip
- 命令:
- unzip RedisBloom-master.zip
- cd RedisBloom-master
- make
-
- 扫行完以上命令 后文件夹内生成一个文件名为:redisbloom.so
- 两个办法
-
-
- 第一,直接修改配置文件
-
- # 进入reids目录 配置在redis.conf中 更加方便
- >> vim redis.conf
-
- # 修改redis配置文件,加入redisboom模块
- >> loadmodule /path/to/redisbloom.so
-
-
-
- 第二,redis启动时加载该模块
- # redis-server 加仓布隆过滤器
- # 参照文档:https://github.com/RedisBloom/RedisBloom#building-and-loading-redisbloom
- >> redis-server --loadmodule /path/to/redisbloom.so
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- # 杀死redis进程
- [root@VM-0-15-centos etc]# ps aux|grep redis
- root 16679 0.0 0.1 153896 2440 ? Ssl 15:10 0:00 ./redis-server 0.0.0.0:6379
- root 30971 0.0 0.0 112712 980 pts/0 R+ 15:17 0:00 grep --color=auto redis
- [root@VM-0-15-centos etc]# kill -9 16679
- [root@VM-0-15-centos etc]# ps aux|grep redis
- root 31436 0.0 0.0 112712 980 pts/0 R+ 15:17 0:00 grep --color=auto redis
-
- # 启动redis服务
- [root@VM-0-15-centos etc]# cd ../bin
- ## 启动redis服务
- [root@VM-0-15-centos bin]# ./redis-server /usr/local/redis/etc/redis.conf
- 32294:C 22 Jan 2021 15:17:40.648 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
- 32294:C 22 Jan 2021 15:17:40.648 # Redis version=5.0.9, bits=64, commit=00000000, modified=0, pid=32294, just started
- 32294:C 22 Jan 2021 15:17:40.648 # Configuration loaded
- [root@VM-0-15-centos bin]# ps aux|grep redis
- root 32295 0.0 0.1 156020 2672 ? Ssl 15:17 0:00 ./redis-server 0.0.0.0:6379
- root 32637 0.0 0.0 112712 984 pts/0 R+ 15:17 0:00 grep --color=auto redis
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
- 127.0.0.1:6379> bf.add mym meituan
- (integer) 1
- 127.0.0.1:6379> bf.exists mym meituan
- (integer) 1
- 127.0.0.1:6379> bf.exists mym baidu
- (integer) 0
- bf.add 添加元素到布隆过滤器,bf.add只能添加一个
- bf.exists 判断元素是否在布隆过滤器
- bf.madd 添加多个元素到布隆过滤器
- bf.mexists 判断多个元素是否在布隆过滤器
例子:
- > bf.add rurl www.baidu.com
- > bf.exists rurl www.baidu.com
- > bf.madd rurl www.sougou.com www.jd.com
- > bf.mexists rurl www.jd.com www.taobao.com
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。