侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Redis实现布隆过滤器的方法及原理

Redis  /  管理员 发布于 5年前   374

布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。

本文将介绍布隆过滤器的原理以及Redis如何实现布隆过滤器。

应用场景

1、50亿个电话号码,现有10万个电话号码,如何判断这10万个是否已经存在在50亿个之中?(可能方案:数据库,set, hyperloglog)
2、新闻客户端看新闻时,它会不断推荐新的内容,每次推荐时都要去重,那么如何实现推送去重?
3、爬虫URL去重?
4、NoSQL数据库领域降低数据库的IO请求数量?
5、邮箱系统的垃圾邮件过滤?

布隆过滤器(Bloom Filter)就是专门来解决这种问题的,它起到去重的同时,在空间上还能节省90%以上,只是存在一定的误判概率。

认识布隆过滤器

布隆过滤器是一种类似set的数据结构,只是不太准确,当用bf.exists判断元素是否存在时返回结果存在但真实不一定存在;当返回不存在时肯定是不存在,所以判断去重时有一定的误判概率。
当然,误判只会发生在过滤器没有添加过的元素,对于添加过的元素不会发生误判。
特点:高效地插入和查询,占用空间少,返回的结果是不确定性的。

布隆过滤器原理

每个布隆过滤器对应到Redis的数据结构中就是一个大型的位数组和几个不同的无偏hash函数,无偏表示分布均匀。

添加key时,使用多个hash函数对key进行hash运算得到一个整数索引值,对位数组长度进行取模运算得到一个位置,每个hash函数都会得到一个不同的位置,将这几个位置都置1就完成了add操作。

查询同理,只要有一位是0就表示这个key不存在,但如果都是1,则不一定存在对应的key。

空间占用估计

布隆过滤器的空间占用有一个简单的计算公式,但推导比较繁琐。布隆过滤器有两个参数,预计元素数量n,错误率f,公式得到两个输出,位数组长度L(即存储空间大小bit),hash函数的最佳数量k。

k = 0.7*(1/n)
f = 0.6185^(L/n)

1、位数组相对长度越长,错误率越低;
2、位数组相对长度越长,需要的hash函数越多;
3、当一个元素平均需要一个字节(8bit)的指纹空间时(L/n=8),错误率大约为2%。

实际元素超出时,误判率会怎样变化?

f = (1-0.5^t)^k  # t为实际元素与预计元素的倍数
1、当错误率为10%时,倍数比为2时,错误率接近40%;
2、当错误率为1%,倍数比为2时,错误率15%;
3、当错误率为0.1%,倍数为2时,错误率5%

Redis实现简单Bloom Filter

要想使用redis提供的布隆过滤器,必须添加redis 4.0版本以上的插件才行,具体参照网上安装步骤。

布隆过滤器有两个基本指令,bf.add添加元素,bf.exists查询元素是否存在,bf.madd一次添加多个元素,bf.mexists一次查询多个元素。

> bf.add spiderurl www.baidu.com
> bf.exists spiderurl www.baidu.com
> bf.madd spiderurl www.sougou.com www.jd.com
> bf.mexists spiderurl www.jd.com www.taobao.com

布隆过滤器在第一次add的时候自动创建基于默认参数的过滤器,Redis还提供了自定义参数的布隆过滤器。

在add之前使用bf.reserve指令显式创建,其有3个参数,key,error_rate, initial_size,错误率越低,需要的空间越大,error_rate表示预计错误率,initial_size参数表示预计放入的元素数量,当实际数量超过这个值时,误判率会上升,所以需要提前设置一个较大的数值来避免超出。

默认的error_rate是0.01,initial_size是100。

利用布隆过滤器减少磁盘 IO 或者网络请求,因为一旦一个值必定不存在的话,我们可以不用进行后续昂贵的查询请求。

总结

以上所述是小编给大家介绍的Redis实现布隆过滤器的方法及原理,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!


  • 上一条:
    Redis实现多人多聊天室功能
    下一条:
    redis实现排行榜的简单方法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在Redis中能实现的功能、常见应用介绍(0个评论)
    • 2024年Redis面试题之一(0个评论)
    • 在redis缓存常见出错及解决方案(0个评论)
    • 在redis中三种特殊数据类型:地理位置、基数(cardinality)估计、位图(Bitmap)使用场景介绍浅析(2个评论)
    • Redis 删除 key用 del 和 unlink 有啥区别?(1个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2017-12
    • 2020-03
    • 2020-05
    • 2021-04
    • 2022-03
    • 2022-05
    • 2022-08
    • 2023-02
    • 2023-04
    • 2023-07
    • 2024-01
    • 2024-02
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客