Redis布隆过滤器

相关链接

redis+布隆过滤器思路图:https://kdocs.cn/l/sgVaSvSB3Z0s

几个小案例

①、原本有10亿个号码,现在又来了10万个号码,要快速准确判断这10万个号码是否在10亿个号码库中?
解决办法一:将10亿个号码存入数据库中,进行数据库查询,准确性有了,但是速度会比较慢。
解决办法二:将10亿号码放入内存中,比如Redis缓存中,这里我们算一下占用内存大小:10亿*8字节=8GB,通过内存查询,准确性和速度都有了,但是大约8gb的内存空间,挺浪费内存空间的。
②、接触过爬虫的,应该有这么一个需求,需要爬虫的网站千千万万,对于一个新的网站url,我们如何判断这个url我们是否已经爬过了?
解决办法还是上面的两种,很显然,都不太好。
③、同理还有垃圾邮箱的过滤。
那么对于类似这种,大数据量集合,如何准确快速的判断某个数据是否在大数据量集合中,并且不占用内存,布隆过滤器应运而生了。

redis+布隆过滤器简单架构图

1、数据结构

布隆过滤器:一种数据结构,是由一串很长的二进制向量组成,可以将其看成一个二进制数组。既然是二进制,那么里面存放的不是0,就是1,但是初始默认值都是0。

image

2、哈希映射

1、布隆需要记录见过的数据,这里的记录需要通过hash函数对数据进行hash操作,得到数组下标并存储在BIT 数组里记为1。这样的记录一个数据只占用1BIT空间

2、判断是否存在时:给布隆过滤器一个数据,进行hash得到下标,从BIT数组里取数据如果是1 则说明数据存在,如果是0 说明不存在

3、精确度

hash算法存在碰撞的可能,所以不同的数据可能hash为一个下标数据,故为了提高精确度就需要 使用多个hash 算法标记一个数据,和增大BIT数组的大小

也是因为如此,布隆过滤器判断为【数据存在】 可能数据并不存在,但是如果判断为【数据不存在】那么数据就一定是不存在的。

4、不支持删除

布隆过滤器只能插入数据判断是否存在,不能删除,而且只能保证【不存在】判断绝对准确

以上不难看出如果给数组的每个BIT位上加一个计数器,插入的时候+1  删除的时候 –1 就可以实现删除

但是加计数器的实现是有问题的:

由于hash碰撞问题,布隆过滤器不能准确判断数据是否存在,就不能随意删除。其次计数器的回绕问题也需要考虑。

5、布隆过滤器优缺点

优点:优点很明显,二进制组成的数组,占用内存极少,并且插入和查询速度都足够快。
缺点:随着数据的增加,误判率会增加;还有无法判断数据一定存在;另外还有一个重要缺点,无法删除数据。

 

给redis安装布隆过滤器模块

1、下载:

地址:https://github.com/RedisBloom/RedisBloom

下载ZIP  文件,上传到linux
RedisBloom-master.zip

2、解压编译

命令:
unzip RedisBloom-master.zip
cd RedisBloom-master
make

扫行完以上命令 后文件夹内生成一个文件名为:redisbloom.so

3、启动redis 时加载该模块

两个办法


第一,直接修改配置文件

# 进入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

4、redis重新启动

# 杀死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

5、测试是否安装成功

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

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页