焦点精选!Redis系列17:聊聊布隆过滤器(实践篇)
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实现消息队列Redis系列16:聊聊布隆过滤器(原理篇)
1 介绍布隆过滤器(Bloom Filter)是 Redis 4.0 版本提供的新功能,我们一般将它当做插件加载到 Redis 服务器中,给 Redis 提供强大的去重功能。它是一种概率性数据结构,可用于判断一个元素是否存在于一个集合中。相比较之 Set 集合的去重功能,布隆过滤器空间上能节省 90% +,不足之处是去重率大约在 99% 左右,那就是有 1% 左右的误判率,这种误差是由布隆过滤器的自身结构决定的。
【资料图】
我们在遇到数据量大的时候,为了去重并避免大批量的重复计算,可以考虑使用 Bloom Filter 进行过滤。具体常用的经典场景如下:
解决大流量下缓存穿透的问题,参考笔者这篇《一次缓存雪崩的灾难复盘》。过滤被屏蔽、拉黑、减少推荐的信息,一般你在浏览抖音或者百度App的时候,看到不喜欢的会设置减少推荐、屏蔽此类信息等,都可以采用这种原理设计。各种名单过滤,使用布隆过滤器实现第一层的白名单或者黑名单过滤,可用于各种AB场景。下面以缓存穿透为解决目标进行讲解。
3 实战介绍缓存穿透是指访问一个不存在的key,缓存不起作用,请求会穿透到DB,流量井喷时会导致DB挂掉。比如 我们查询用户的信息,程序会根据用户的编号去缓存中检索,如果找不到,再到数据库中搜索。如果你给了一个不存在的编号:XXXXXXXX,那么每次都比对不到,就透过缓存进入数据库。这样风险很大,如果因为某些原因导致大量不存在的编号被查询,甚至被恶意伪造编号进行攻击,那将是灾难。解决方案质疑就是在缓存之前在加一层 BloomFilter :
把存在的key记录在BloomFilter中,在查询的时候先去 BloomFilter 去查询 key 是否存在,如果不存在则说明数据库和缓存都没有,就直接返回,存在再走查缓存 ,投入数据库去查询,这样减轻了数据库的压力。3.1 巨量查询信息案例解析下面以火车票订购和查询为案例进行说明,如果火车票被恶意攻击,模拟了一模一样的火车票订单编号,那很可能通过大量的请求穿透过缓存层把数据库打雪崩了,所以使用布隆过滤器为服务提供一层保障。具体的做法就是,我们在购买火车票成功的时候,把订单号的ID写入(异步或者消息队列的方式)到布隆过滤器中,保障后续的查询都在布隆过滤器中走一遍再进到缓存中去查询。火车票订单Id同步到 Bloom Filter 的步骤如下:
3.2 创建Bloom Filter的方式创建 Bloom Filter 的语法如下:
# BF.RESERVE {key} {error_rate} {capacity} [EXPANSION {expansion}] [NONSCALING]BF.RESERVE ticket_orders 0.01 1000000key:布隆过滤器的名字,这边指的是创建一个名为 ticket_orders 的过滤器。error_rate:期望的错误率,默认值为 0.1,值越低,需要的空间越大。就像我们上一节说的,空间越大碰撞的可能性越低。capacity:初始的空间容量,默认值为 100,当实际元素的数量超过这个初始化容量时,碰撞的可能性越高,误判率也越高。EXPANSION:可选参,数据达到初始容量后,布隆过滤器会自动创建一个子过滤器,大小为上一个过滤器乘以 expansion。expansion 的默认值为 2,也就是说默认扩容2倍;NONSCALING:可选参,指的是数据达到初始容量后,不会扩容过滤器,并抛出异常((error) ERR non scaling filter is full)。而上面那句命令是,通过BF.RESERVE命令手动创建一个名字为 ticket_orders,错误率为 0.01 ,初始容量为 1000000 的布隆过滤器。这边需要注意的一些点是:
error_rate 越小,对碰撞的容忍度越小,需要的存储空间就越大。如果允许一定比例的不准确,对精确度要求不高的场景,error_rate 可以设的稍大一点。capacity 设置的过大,会浪费存储空间,设置过小,准确度不高。所以评估的时候需要精准一点,既要避免浪费空间也要保证准确比例。3.3 添加火车票订单Id到Bloom Filter# BF.ADD {key} {value ... }# 添加单个订单号BF.ADD ticket_orders 2023061008795(integer) 1# 添加多个订单号BF.MADD ticket_orders 2023061008796 2023061008797 20230610087981) (integer) 12) (integer) 13) (integer) 1以上的语句是将已经订好的车票订单号存储到Bloom Filter中,包括一次存储单个和一次存储多个。
3.4 判断火车票订单Id是否存在# BF.EXISTS {key} {value} ,存在的话返回 1,不存在返回 0BF.EXISTS ticket_orders 2023061008795(integer) 1# 批量判断多个值是否存在于布隆过滤器,语句如下:BF.MEXISTS ticket_orders 2023061008796 2023061008797 20230610087981) (integer) 02) (integer) 13) (integer) 0BF.EXISTS 判断一个元素是否存在于 Bloom Filter中,返回值 = 1 表示存在,返回值 = 0 表示不存在。可以一次性判断单个元素,或者一次性判断多个元素。
3.5 Review已建的布隆过滤器列表# 使用 BF.INFO {key} 语法查看BF.INFO ticket_orders 1) Capacity 2) (integer) 1000000 3) Size 4) (integer) 3 5) Number of filters 6) (integer) 1 7) Number of items inserted 8) (integer) 3 9) Expansion rate10) (integer) 2返回值解析:Capacity:预设容量,我们前面设置了1000000。Size:实际占用情况,我们前面设置了3个值:2023061008796、 2023061008797、 2023061008798。Number of filters:过滤器的层数。Number of items inserted:实际已插入的元素数量。Expansion rate:子过滤器扩容的系数,咱们前面创建的时候未设值,所以这边是默认 2。
综上,我们通过 BF.RESERVE、BF.ADD、BF.EXISTS、BF.INFO 等几个指令就能实现布隆过滤器的建设,避免缓存穿透的情况发生。因为你查询缓存的时候,必然你先到Bloom Filter中先过滤一次,这样就不会因为无效的key把缓存打穿。
4 程序实现说明Spring Boot版本: 2.5.x。
4.1 添加 Redission Maven 依赖如果实际情况可以使用更高版本
org.redisson redisson-spring-boot-starter 3.17.1 4.2 Spring boot Yaml中的 Redission 配置spring: application: name: redission redis: cluster: nodeAddresses: [ "redis://127.0.0.1:8000", "redis://127.0.0.1:8001", "redis://127.0.0.1:8002", "redis://127.0.0.1:8003", "redis://127.0.0.1:8004", "redis://127.0.0.1:8005" ] password: ******** single: address: "redis://127.0.0.1:6379" database: 64.3 创建布隆过滤器相关@Servicepublic class BloomFilterService { @Autowired private RedissonClient redissonClient; /** * 创建布隆过滤器 * @param filterKey 过滤器名称,等同上面的key * @param expectedCapacity 预计元素容量,等同于上面的capacity * @param falseRate 允许的误判率,等同于上面的error_rate * @param * @return */ public RBloomFilter create(String filterKey, long expectedCapacity, double falseRate) { // 集群模式 RClusteredBloomFilter bloomFilter = redissonClient.getClusteredBloomFilter(filterKey); // 以下是单实例模式// RBloomFilter bloomFilter = redissonClient.getBloomFilter(filterKey); bloomFilter.tryInit(expectedCapacity, falseRate); return bloomFilter; }} 4.4 测试实现@Autowired private BloomFilterService bloomFilterService; @Test public void testBloomFilter() { // 预计元素容量 1000000 long expectedCapacity = 1000000L; // 错误率 double falseRate = 0.01; RBloomFilter bloomFilter = bloomFilterService.create("ticket_orders", expectedCapacity, falseRate); // 元素增加测试并输出统计 for (long idx = 0; idx < expectedCapacity; idx++) { bloomFilter.add(idx); } long eleCount = bloomFilter.count(); log.info("eleCount = {}.", elementCount); } 5 总结本篇介绍了布隆过滤器的几种实现场景。并以火车票订单信息查询为案例进行说明,如何使用布隆过滤器避免缓存穿透,避免被恶意攻击。
标签:
-
2022-02-07 14:57:45
奇迹!绝杀!女足亚洲杯逆转夺冠!<
刚刚,中国女足上演逆转绝杀奇迹!她们在亚洲杯决赛中3:2力克韩国队,时隔16年再夺亚洲杯冠军!
-
2022-02-07 14:57:45
中国政府与阿根廷共和国政府签署共建“一带一路”谅解备忘录<
新华社北京2月6日电(记者安蓓)国家发展改革委6日称,国家发展改革委主任何立峰与阿根廷外交、国际贸易和宗教事
-
2022-02-07 14:57:43
中华人民共和国和阿根廷共和国关于深化中阿全面战略伙伴关系的联合声明(全文)<
新华社北京2月6日电中华人民共和国和阿根廷共和国关于深化中阿全面战略伙伴关系的联合声明一、应中方邀请,阿根廷
-
2022-02-07 14:57:40
春节假期国内旅游出游2.51亿人次<
春节遇冬奥,旅游年味浓。根据文化和旅游部数据中心测算,2022年春节假期7天,全国国内旅游出游2 51亿人次,同比
-
2022-02-07 14:57:40
中吉签署关于经典著作互译出版的备忘录 开启两国人文交流互鉴新阶段<
新华社北京2月6日电(记者史竞男)国家主席习近平6日会见来华出席北京2022年冬奥会开幕式的吉尔吉斯斯坦总统扎帕
-
2023-06-14 15:17:21
焦点精选!Redis系列17:聊聊布隆过滤器(实践篇)
[Redis系列1:深刻理解高性能Redis的本质](https: www cnblogs com wz
-
2023-06-14 15:05:58
什么是腐蚀电池(什么是腐女?)
1、1腐女是一个中文词汇,全称是腐女(12即BLBoys & 039;Love的缩写,翻译过
-
2023-06-14 14:59:36
“逆水寒”手游“碰瓷式”营销背后,手游营销正在内卷? 世界视点
作为网易今年首个拿到版号的超级项目,从KFC疯狂星期四文学到“挖呀挖
-
2023-06-14 14:36:29
荣盛发展再度涨停
录得4连板。
-
2023-06-14 14:16:11
猪肉芹菜水饺的制作方法是什么呢?猪肉芹菜水? 今日热讯
猪肉芹菜饺子馅做法大全里有写,1、将芹菜切碎备用。2、将浓汤宝加至肉
-
2023-06-14 13:47:58
《守望先锋2》PVE阉割后仍需付费 玩家不满
暴雪在近日发布了一篇文章,针对《守望先锋2》的“入侵”PVE扩展内容需
-
2023-06-14 13:41:13
苯丙酮尿症 苯丙酮尿症西红柿女孩|实时
1、简言苯丙酮尿症治疗主要采取饮食疗始治疗龄愈效愈低苯丙氨酸饮食应
-
2023-06-14 13:24:23
焦点要闻:姆巴佩巴黎翻脸,皇马幕后玩家!2大超巨作先锋,熊皇成最后阻碍
赛季结束不久,银河战舰就率先出手,花费过亿欧元转会费,将贝林厄姆招
-
2023-06-14 13:00:05
安徽阿玛达机床制造有限公司
1、安徽阿玛达机床制造有限公司于2018年08月24日成立。2、法定代表人王
-
2023-06-14 12:44:23
谭龙:想帮亚运队终止连续3届无缘八强的尴尬 要带动年轻球员成长
直播吧6月14日讯在接受《北京青年报》采访时,以超龄球员身份入选男足
-
2023-06-14 12:17:50
带有全景窗户和玻璃天花板的未来巴士将在马德里运行
带有全景窗户和玻璃天花板的未来巴士应该会出现在马德里的公交线路上。
-
2023-06-14 12:08:47
天天关注:此功能可以使摩托罗拉Razr成为迄今为止最好的可折叠手机
最佳可折叠手机的竞赛比以往任何时候都更加激烈。无论您是选择书本式可
-
2023-06-14 11:40:58
烟台公积金中心电话号码_问一下烟台公积金管理中心的电话相关介绍简介-世界新要闻
市管理中心办公地点:南大街111号征收管理科:666926266692616669260贷
-
2023-06-14 11:40:06
湖人麻烦来了!火箭或抢里夫斯,6000万空间不差钱,詹皇失帮手?
哈登在休赛期成为完全自由球员,此前费城媒体爆料哈登将回归火箭,但是
-
2023-06-14 11:13:25
英可瑞6月14日快速反弹|焦点滚动
以下是英可瑞在北京时间6月14日11:10分盘口异动快照:6月14日,英可瑞
-
2023-06-14 11:04:13
全球报道:黄牛背后的“大牛”们
黄牛背后的“大牛”们,抢票,家牛,五月天,金牛犊,一票难求,驯养动物
-
2023-06-14 11:09:54
环球快播:《绵阳市水污染防治条例(修订草案代拟稿)》征求意见
《绵阳市水污染防治条例(修订草案代拟稿)》征求意见6月12日,绵阳市
-
2023-06-14 10:41:45
每日热议!能源转型孕育巨大投资机遇 减污降碳要关注公正性
“双碳”目标背景下,全球温控窗口收紧,如何采取行动增强能源系统韧性
-
2023-06-14 10:23:27
环球快讯:长路
作为一名马拉松老将,何引丽知道一个微小的变量会导致结果的不同。在20
-
2023-06-14 10:04:39
精选!翊圣真君宝诰(翊圣真君)
1、翊圣真君是北极四圣之一。2、但西斗则是西方白虎七宿,即:奎、娄(l
-
2023-06-14 09:46:38
新增建设200所高职院校与应用本科,有何深意? 天天动态
据媒体报道,我国将新增200所左右高职院校和应用型本科院校,推动形成
-
2023-06-14 09:58:21
微博二维码怎么生成的_微博二维码怎么生成
1、步骤:一,百度搜”二维码生成器“,打开网页;二,拷贝你要转换的
-
2023-06-14 09:22:49
Best Agrolife在印度首家推出三元复配杀菌剂Tricolor(肟菌酯+苯醚甲环唑+硫磺)
世界农化网中文网报道:印度农化行业主要公司之一BestAgrolifeLimited(
-
2023-06-14 09:04:39
安阳市开展水上救援应急实战演练-焦点简讯
我市开展水上救援应急实战演练6月11日,市交通运输局交通运输服务中心
-
2023-06-14 08:57:28
【新要闻】滁州市南谯区开展“为企优服务提升年”活动
为持续深化“一改两为”,近日,滁州市南谯区出台“为企优服务提升年”
-
2023-06-14 08:59:34
嶒泓
1、嶒泓,汉语词语,拼音是cénghóng,意思是空洞寥落。2、。本文到此
-
2023-06-14 08:20:10
世界关注:警方通报天津河东爆炸案:嫌疑人已被抓获,系利用烟花爆竹作案
6月14日凌晨,天津河东区公安分局发布情况通报,内容如下:2023年6月13
-
2023-06-14 08:11:23
小仓鼠爱打架怎么办(小仓鼠打架怎么办简介介绍)
对于小仓鼠打架怎么办这个问题感兴趣的朋友应该很多,这个也是目前大家
-
2023-06-14 07:57:22
marco.polo_marco polo_每日热讯
1、马可波罗是一个人,他是一个很著名的旅行家。2、马可·波罗(MarcoPo
-
2023-06-14 07:24:48
1月内执教2支中甲队!前国脚再挑重担,首秀即保级战,力避7连败|速读
在中甲第6轮无锡吴钩1-2不敌广西平果哈嘹之后,杨林交出了帅印。在杨林