Redis 中的布隆过滤器

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis 中的布隆过滤器


什么是『布隆过滤器』

布隆过滤器是一个神奇的数据结构,可以用来判断一个元素是否在一个集合中。很常用的一个功能是用来去重。在爬虫中常见的一个需求:目标网站 URL 千千万,怎么判断某个 URL 爬虫是否宠幸过?简单点可以爬虫每采集过一个 URL,就把这个 URL 存入数据库中,每次一个新的 URL 过来就到数据库查询下是否访问过。

select id from table where url = 'https://jaychen.cc'
复制代码

但是随着爬虫爬过的 URL 越来越多,每次请求前都要访问数据库一次,并且对于这种字符串的 SQL 查询效率并不高。除了数据库之外,使用 Redis 的 set 结构也可以满足这个需求,并且性能优于数据库。但是 Redis 也存在一个问题:耗费过多的内存。这个时候布隆过滤器就很横的出场了:这个问题让我来。

相比于数据库和 Redis,使用布隆过滤器可以很好的避免性能和内存占用的问题。

布隆过滤器本质是一个位数组,位数组就是数组的每个元素都只占用 1 bit 。每个元素只能是 0 或者 1。这样申请一个 10000 个元素的位数组只占用 10000 / 8 = 1250 B 的空间。布隆过滤器除了一个位数组,还有 K 个哈希函数。当一个元素加入布隆过滤器中的时候,会进行如下操作:

  • 使用 K 个哈希函数对元素值进行 K 次计算,得到 K 个哈希值。
  • 根据得到的哈希值,在位数组中把对应下标的值置为 1。

举个🌰,假设布隆过滤器有 3 个哈希函数:f1, f2, f3 和一个位数组 arr。现在要把 https://jaychen.cc 插入布隆过滤器中:

  • 对值进行三次哈希计算,得到三个值 n1, n2, n3。
  • 把位数组中三个元素 arr[n1], arr[n2], arr[3] 置为 1。

当要判断一个值是否在布隆过滤器中,对元素再次进行哈希计算,得到值之后判断位数组中的每个元素是否都为 1,如果值都为 1,那么说明这个值在布隆过滤器中,如果存在一个值不为 1,说明该元素不在布隆过滤器中。

看不懂文字看下面的灵魂画手的图解释👇👇👇

看了上面的说明,必然会提出一个问题:当插入的元素原来越多,位数组中被置为 1 的位置就越多,当一个不在布隆过滤器中的元素,经过哈希计算之后,得到的值在位数组中查询,有可能这些位置也都被置为 1。这样一个不存在布隆过滤器中的也有可能被误判成在布隆过滤器中。但是如果布隆过滤器判断说一个元素不在布隆过滤器中,那么这个值就一定不在布隆过滤器中。简单来说:

  • 布隆过滤器说某个元素在,可能会被误判。
  • 布隆过滤器说某个元素不在,那么一定不在。

这个布隆过滤器的缺陷放到上面爬虫的需求中,可能存在某些没有访问过的 URL 可能会被误判为访问过,但是如果是访问过的 URL 一定不会被误判为没访问过。

Redis 中的布隆过滤器

redis 在 4.0 的版本中加入了 module 功能,布隆过滤器可以通过 module 的形式添加到 redis 中,所以使用 redis 4.0 以上的版本可以通过加载 module 来使用 redis 中的布隆过滤器。但是这不是最简单的方式,使用 docker 可以直接在 redis 中体验布隆过滤器。

> docker run -d -p 6379:6379 --name bloomfilter redislabs/rebloom
> docker exec -it bloomfilter redis-cli
复制代码

redis 布隆过滤器主要就两个命令:

上面说过布隆过滤器存在误判的情况,在 redis 中有两个值决定布隆过滤器的准确率:

  • error_rate:允许布隆过滤器的错误率,这个值越低过滤器的位数组的大小越大,占用空间也就越大。
  • initial_size:布隆过滤器可以储存的元素个数,当实际存储的元素个数超过这个值之后,过滤器的准确率会下降。

redis 中有一个命令可以来设置这两个值:

bf.reserve urls 0.01 100
复制代码

三个参数的含义:

  • 第一个值是过滤器的名字。
  • 第二个值为 error_rate 的值。
  • 第三个值为 initial_size 的值。

使用这个命令要注意一点:执行这个命令之前过滤器的名字应该不存在,如果执行之前就存在会报错:(error) ERR item exists




相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
7月前
|
缓存 NoSQL Apache
【Redis】布隆过滤器原理与应用
【Redis】布隆过滤器原理与应用
95 1
|
7月前
|
存储 缓存 NoSQL
Redis 布隆过滤器实战「缓存击穿、雪崩效应」
Redis 布隆过滤器实战「缓存击穿、雪崩效应」
169 1
Redis 布隆过滤器实战「缓存击穿、雪崩效应」
|
7月前
|
NoSQL 算法 程序员
【Redis】布隆过滤器
【Redis】布隆过滤器
|
7月前
|
存储 缓存 NoSQL
在Java中实现redis缓存中的布隆过滤器
在Java中实现redis缓存中的布隆过滤器
156 0
|
缓存 NoSQL 安全
Redis缓存雪崩、击穿、穿透解释及解决方法,缓存预热,布隆过滤器 ,互斥锁
Redis缓存雪崩、击穿、穿透解释及解决方法,缓存预热,布隆过滤器 ,互斥锁
255 5
|
6月前
|
NoSQL Redis 数据库
【Redis从入门到入土】布隆过滤器简介、特点和原理
【6月更文挑战第1天】布隆过滤器是一种节省内存的不确定数据结构,用于判断元素是否可能在一个集合中。它由位数组和多个哈希函数组成,能快速插入和查询,但存在误判风险:可能存在假阳性(判断存在但实际不存在),但绝无假阴性(判断不存在则确实不存在)。适用于大规模数据的去重问题,如电话号码判断、安全网站链接检查、黑名单和白名单校验。其工作原理是通过多个哈希函数将元素映射到位数组中,添加时设置相应位置为1,查询时所有位置都为1则可能存在,有0则肯定不存在。由于哈希冲突,可能导致误判,且一旦添加元素无法删除,以避免影响其他元素。
72 4
|
7月前
|
缓存 NoSQL 算法
【redis】布隆过滤器(Bloom Filter)原理解析与应用
【redis】布隆过滤器(Bloom Filter)原理解析与应用
109 1
|
7月前
|
存储 NoSQL 算法
深入浅出Redis(十一):Redis四种高级数据结构:Geosptial、Hypeloglog、Bitmap、Bloom Filter布隆过滤器
深入浅出Redis(十一):Redis四种高级数据结构:Geosptial、Hypeloglog、Bitmap、Bloom Filter布隆过滤器
|
7月前
|
缓存 NoSQL Redis
Redis系列-9.Redis布隆过滤器BloomFilter
Redis系列-9.Redis布隆过滤器BloomFilter
109 1
|
7月前
|
存储 缓存 NoSQL
Redis进阶-布隆过滤器
Redis进阶-布隆过滤器
121 0
下一篇
DataWorks