Redis系列16:聊聊布隆过滤器(原理篇)
Redis系列1:深刻理解高性能Redis的本质
Redis系列2:数据持久化提高可用性
Redis系列3:高可用之主从架构
Redis系列4:高可用之Sentinel(哨兵模式)
Redis系列5:深入分析Cluster 集群模式
追求性能极致:Redis6.0的多线程模型
追求性能极致:客户端缓存带来的革命
Redis系列8:Bitmap实现亿万级数据计算
Redis系列9:Geo 类型赋能亿级地图位置计算
Redis系列10:HyperLogLog实现海量数据基数统计
Redis系列11:内存淘汰策略
Redis系列12:Redis 的事务机制
Redis系列13:分布式锁实现
Redis系列14:使用List实现消息队列
Redis系列15:使用Stream实现消息队列
1 Bloom Filter 介绍
布隆过滤器(Bloom Filter)是 Redis 4.0 版本提供的新功能,我们一般将它当做插件加载到 Redis 服务器中,给 Redis 提供强大的去重功能。
它是一种概率性数据结构,可用于判断一个元素是否存在于一个集合中。相比较之 Set 集合的去重功能,布隆过滤器空间上能节省 90% +,不足之处是去重率大约在 99% 左右,那就是有 1% 左右的误判率,这种误差是由布隆过滤器的自身结构决定的。
- 优点:空间效率和查询时间都比一般的算法要好的多
- 缺点:有一定的误识别率和删除困难
2 原理分析
布隆过滤器(Bloom Filter)是一个高空间利用率的概率性数据结构,由二进制向量(即位数组)和一系列随机映射函数(即哈希函数)两部分组成。
通过使用exists()来判断某个元素是否存在于自身结构中。当布隆过滤器判定某个值存在时,其实这个值只是有可能存在;当它说某个值不存在时,那这个值肯定不存在,这个误判概率大约在 1% 左右。
原理拆解如下:
- 在一个很长的二进制向量和一系列随机映射函数的基础上,将元素哈希成不同的位置,每个位置对应二进制向量中的一个比特位。
- 当加入一个元素时,采用 n 个相互独立的 Hash 函数计算key,然后将元素 Hash 映射的 n 个位置全部设置为 1。
- 检测 key 是否存在,仍然用 Hash 函数计算出这 n 个位置,如果元素key 存在于集合中,则对应的位置为1,否则为0。
- 如果n个位置均为1的话,可以确定元素key可能存在于集合中;如果有一个为0,那么元素的key一定不存在于集合中,下面会详细分析这句话。
- 这种判断机制会存在误判的可能,但它以较小的空间代价和极简的时间复杂度来近似解决集合交、并、差等操作。
2.1 添加元素步骤

当使用布隆过滤器添加 key 时,会使用不同的 hash 函数对 key 存储的元素值进行哈希计算,从而会得到多个哈希值。根据哈希值计算出一个整数索引值,将该索引值与位数组长度做取余运算,最终得到一个位数组位置,并将该位置的值变为 1。每个 hash 函数都会计算出一个不同的位置,然后把数组中与之对应的位置变为 1。这边可能出现元素碰撞的情况,比如位置3,a元素和b元素的hash计算位置一致,所以出现了碰撞。
2.2 判定元素是否存在步骤
如果我们要判定一个元素是否存在,需要如下步骤:
- 首先对给定元素key执行哈希计算,这样可以得到元素增加时的bit位数组位置
- 判断这些位置是否都为 1,如果其中有一个为 0,那么说明元素不存在
- 若全部位置都为 1,则说明元素有可能存在。
为啥说是可能存在呢,因为上面说过了,哈希函数出的结果会出现碰撞,所以布隆过滤器会存在误判。

如上图c,他的位置被其他元素的位置完全覆盖,即使c没有存储,对应位置上也被a和b的Hash函数设置为1,这时候就可能误判为c是有存储的。
有概率存在这样的 key,它们内容不同,但多次 Hash 后的 Hash 值都相同。
2.3 元素删除步骤
一般不会删除元素,我们上面说了,因为可能存在碰撞情况,所以也有可能存在误删除情况。

删除意味着需要将对应的 n 个 bits 位置设置为 0,其中有可能是其他元素对应的位。
比如图中的b删除之后,位置3的值也被设置为0,这样a也可能会被判定为不存在。
3 使用场景介绍
我们在遇到数据量大的时候,为了去重并避免大批量的重复计算,可以考虑使用 Bloom Filter 进行过滤。
具体常用的经典场景如下:
- 解决大流量下缓存穿透的问题,参考笔者这篇《一次缓存雪崩的灾难复盘》。
- 过滤被屏蔽、拉黑、减少推荐的信息,一般你在浏览抖音或者百度App的时候,看到不喜欢的会设置减少推荐、屏蔽此类信息等,都可以采用这种原理设计。
- 各种名单过滤,使用布隆过滤器实现第一层的白名单或者黑名单过滤,可用于各种AB场景。
4 安装集成
如果是自己编译安装,可以从 github 下载,目前的latest 的 release 版本是 v2.4.5,下载地址如下:
https://github.com/RedisBloom/RedisBloom/releases/tag/v2.4.5

直接按照编译的方式进行安装:
# 解压文件:
tar -zxvf tar -zxvf RedisBloom-2.4.5.tar.gz
# 进入目录:
cd RedisBloom-2.4.5
# 执行编译命令,生成redisbloom.so 文件:
make
# 拷贝至指定目录:
cp redisbloom.so /usr/local/redis/RedisBloom-2.4.5/redisbloom.so
# 需要修改 redis.conf 文件,新增 loadmodule配置,并重启 Redis。
# 在redis配置文件里加入以下配置:
loadmodule /usr/local/redis/RedisBloom-2.4.5/redisbloom.so
# 配置完成后重启redis服务:
redis-server /usr/local/redis/RedisBloom-2.4.5/redis.conf
# 测试是否安装成功
127.0.0.1:6379> bf.add user brand
(integer) 1
127.0.0.1:6379> bf.exists user brand
(integer) 1
5 总结
大致说了布隆过滤器的原理和使用场景,下一篇我们来看看实战。
Redis系列16:聊聊布隆过滤器(原理篇)的更多相关文章
- 浅谈redis的HyperLogLog与布隆过滤器
首先,HyperLogLog与布隆过滤器都是针对大数据统计存储应用场景下的知名算法. HyperLogLog是在大数据的情况下关于数据基数的空间复杂度优化实现,布隆过滤器是在大数据情况下关于检索一个元 ...
- Bloom Filter布隆过滤器原理和实现(1)
引子 <数学之美>介绍布隆过滤器非常经典: 在日常生活中,包括设计计算机软件时,经常要判断一个元素是否在一个集合中.比如: 在字处理软件中,需要检查一个英语单词是否拼写正确(也就是要判断它 ...
- Redis解读(4):Redis中HyperLongLog、布隆过滤器、限流、Geo、及Scan等进阶应用
Redis中的HyperLogLog 一般我们评估一个网站的访问量,有几个主要的参数: pv,Page View,网页的浏览量 uv,User View,访问的用户 一般来说,pv 或者 uv 的统计 ...
- redis 系列16 持久化 RDB
一.概述 Redis是内存数据库,一旦服务器进程退出,服务器中的数据库内存数据状态也会消失.为了解决这个问题,Redis提供了RDB 持久化功能,这个功能可以将redis在内存中的数据库状态保存到磁盘 ...
- 硬核 | Redis 布隆(Bloom Filter)过滤器原理与实战
在Redis 缓存击穿(失效).缓存穿透.缓存雪崩怎么解决?中我们说到可以使用布隆过滤器避免「缓存穿透」. 码哥,布隆过滤器还能在哪些场景使用呀? 比如我们使用「码哥跳动」开发的「明日头条」APP 看 ...
- SpringBoot(18)---通过Lua脚本批量插入数据到Redis布隆过滤器
通过Lua脚本批量插入数据到布隆过滤器 有关布隆过滤器的原理之前写过一篇博客: 算法(3)---布隆过滤器原理 在实际开发过程中经常会做的一步操作,就是判断当前的key是否存在. 那这篇博客主要分为三 ...
- python实现布隆过滤器及原理解析
python实现布隆过滤器及原理解析 布隆过滤器( BloomFilter )是一种数据结构,比较巧妙的概率型数据结构(probabilistic data structure),特点是高效地 ...
- 布隆过滤器(Bloom Filter)原理以及应用
应用场景 主要是解决大规模数据下不需要精确过滤的场景,如检查垃圾邮件地址,爬虫URL地址去重,解决缓存穿透问题等. 布隆过滤器(Bloom Filter)是1970年由布隆提出的.它实际上是一个很长的 ...
- 【目录】redis 系列篇
随笔分类 - redis 系列篇 redis 系列27 Cluster高可用 (2) 摘要: 一. ASK错误 集群上篇最后讲到,对于重新分片由redis-trib负责执行,关于该工具以后再介绍.在进 ...
- 详细解析Redis中的布隆过滤器及其应用
欢迎关注微信公众号:万猫学社,每周一分享Java技术干货. 什么是布隆过滤器 布隆过滤器(Bloom Filter)是由Howard Bloom在1970年提出的一种比较巧妙的概率型数据结构,它可以告 ...
随机推荐
- scp上传文件No such file or directory 问题
问题描述 window使用scp复制文件到linux时报 No such file or directory 错误 解决办法 本地复制到Linux,win环境必须用绝对路径 上传成功
- GKCTF X DASCTF应急挑战杯-Maple_root-Writeup
GKCTF X DASCTF应急挑战杯-Maple_root-Writeup 参赛队员: b4tteRy, x0r, f1oat 最终成绩:2285 最终排名:27 总结 经过最近几次类线下的演练,感 ...
- Java BIO,NIO,AIO
一丶IO模型&Java IO Unix为程序员提供了以下5种基本的io模型: blocking io: 阻塞io nonblocking io: 非阻塞io I/O multiplexing: ...
- elk7.15.1安装部署搭建
ELK简介 ELK是Elasticsearch.Logstash.Kibana三大开源框架首字母大写简称(但是后期出现的Filebeat(beats中的一种)可以用来替代Logstash的数据收集功能 ...
- django模糊查询排序
class Book(models.Model): """ 列名 """ class Meta: db_table = 'book' nam ...
- 如果你项目使用了MyBatis-Plus你一定要用它
还是先举个例子,魂斗罗小游戏应该很多90后都玩过,那个时代没有Iphone,没有各种电子产品(小学初中时代),这种小游戏应该就是很多90后的青春,反正那个时候只要放假就白天黑夜得玩.它就是那种2个好基 ...
- C# 组合键判断
e.KeyboardDevice.Modifiers 同时按下了Ctrl + H键(H要最后按,因为判断了此次事件的e.Key)修饰键只能按下Ctrl,如果还同时按下了其他修饰键,则不会进入 1 pr ...
- MySQL中的Join 的算法(NLJ、BNL、BKA)
本文已收录至Github,推荐阅读 Java随想录 微信公众号:Java随想录 目录 摘要 什么是Join Index Nested-Loop Join Block Nested-Loop Join ...
- 2023-04-24:用go语言重写ffmpeg的muxing.c示例。
2023-04-24:用go语言重写ffmpeg的muxing.c示例. 答案2022-04-24: 本程序的大体过程如下: 打开输出文件并写入头部信息. 添加音频和视频流,并为每个流创建 AVCod ...
- golang在编程语言排行榜上排名第10,请不要说golang已死。
四月头条:编程语言 Zig 进入 TIOBE 指数前 50 名 最近,我们讨论了高性能编程语言的出现.由于需要处理的数据量越来越大,这些编程语言正在蓬勃发展.因此,C 和 C++ 在前十名中表现良好, ...