布隆过滤器

简介

布隆过滤器(Bloom Filter)是 Redis 中的海量数据去重或过滤工具。需手动下载,并在 Redis 的配置文件中加载 redisbloom.so 模块。

布隆过滤器是一种高空间利用率的概率型数据结构

常用于判断某个元素是否存在于一个集合中。虽然这个判断只是一个概率性的结果,并不完全准确。但只要正确使用,在足够大体量的数据中,误判的概率可以忽略不计

当布隆过滤器判定某个元素存在时,这个元素只是可能存在;当判定某个元素不存在时,这个元素肯定不存在。

原理

在 Redis 中,布隆过滤器由一个位数组和一系列哈希函数组成。

当我们向布隆过滤器中添加一个元素时,会调用多个(假设是 3 个)哈希函数进行计算,得出几个整型索引值,索引匹配对应到位数组,将位数组中那几个索引位置的值标记为 1(初始时位数组中所有的值默认都是 0)。

当判断一个元素是否存在于集合中时,也是调用这几个哈希函数进行计算,得出几个整型索引值。如果位数组中这几个索引位置的值全部为 1,就认为该元素可能(也许是误判)存在于集合中;否则,就说明该元素一定不在集合中。

误判的概率与位数组的长度、哈希算法计算的次数有关。

位数组越长、哈希算法计算次数越多、插入元素越少,误判率就越低。

计算公式如下:

h≈0.7*(m/n)

p≈0.6185^(m/n)

其中:

  • m 表示位数组的长度,位数组越长,占用空间越大。
  • n 表示元素的数量。
  • h 表示最佳的哈希函数的数量。
  • p 表示误判率。

由公式可知:位数组的长度 m 越长,误判率 p 越低;位数组 m 越长,哈希函数最佳的数量 h 越多;哈希函数越多,计算花费的时间越长。

通过上面的公式,还可以得出:p=0.0001% 时,每个元素才占 28.8 bit。

也就是说,误判率 p=0.0001% 时,每个元素只占用 28.8 bit,就算存储 100 万个元素,只会占用 27.5 MB的存储空间。

布隆过滤器在查询速度和存储方式两个方面都非常优秀。

基本用法

# 创建一个误判率为 0.01%、可存储 10k 个元素的布隆过滤器
bf.reserve myfilter 0.0001 10000

# 查看布隆过滤器的信息
bf.info myfilter

# 添加元素到布隆过滤器中
bf.add myfilter test1001@gmail.com

# 判断元素是否在布隆过滤器集合中
bf.exists myfilter test1001@gmail.com

应用场景

(1)解决缓存穿透等缓存问题

将数据库(MySQL)层相关的缓存的键(key),都提前存入布隆过滤器中。用来判断请求的键是否在底层的数据库中。

可以将布隆过滤器的判断逻辑,置于查询 Redis 缓存之前。请求在查询 Redis 缓存之前,先判断请求的 key 是否存在于布隆过滤器中。如果在,就查询缓存,如果缓存中没有,才去查询数据库;如果不在布隆过滤器中,就直接返回。

当然,也可以把布隆过滤器的层级放到数据库的上一层。请求数据时,先去缓存查询。如果缓存里有,就直接返回结果;如果缓存里没有,就先判断是否在布隆过滤器中。如果在,才允许查询 MySQL 数据库,如果不在布隆过滤器中,就直接返回。

通过前置一层布隆过滤器,可以将绝大部分的穿透查询屏蔽在 Redis 层,极大地降低了底层数据库的压力。

(2)避免爬虫 URL 重复

将爬虫爬过的 URL 存入布隆过滤器中。每次爬取之前先判断目标 URL 是否在布隆过滤器中,如果在,就不需要重复爬取;否则,才执行爬取操作。

(3)黑白名单权限过滤

将白名单存入布隆过滤器中。当用户发起请求操作时,先判断其是否存在于布隆过滤器中,如果在,才允许请求。黑名单也是类似。

(4)避免消息推送给同样的人

将发送过消息的用户唯一标识符存入布隆过滤器中。下次发送此消息时,先判断其是否存在于布隆过滤器中,如果不在,才进行推送。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值