1、简介
在海量数据下判断某个值是否存在时,如果使用匹配方式是非常耗时耗力的,因此布隆过滤器因此而生,布隆过滤器可以从海量数据中判断某个值是否存在,但是有一定的误差。布隆过滤器的特性是:如果判断某个值不存在就一定不存在;如果判断某个值存在可能不存在。
2、布隆过滤器(BloomFilter)原理
布隆过滤器是一个初始值为零的bit数组和多个hash函数组成,本质是判断某个数是否在大数据集合中。它能够高效实现插入和查询,但是有瑕疵的是对于存在的判断结果存在一定的偏差,如下图所示。
添加key时,使用多个hash函数对key进行hash运算得到一个整数索引值,对位数组长度进行取模运算得到一个位置,每个hash函数都会得到一个不同的位置,将这几个位置都置1就完成了add操作。
查询key时只要有其中一位是零就表示这个key不存在,但如果都是1,则不一定存在对应的key(为什么说是不一定存在,而不是一定存在呢?那是因为映射函数本身就是散列函数,散列函数是会有碰撞的)。
3、布隆过滤器实现
3.1、初始化bit数组
布隆过滤器 本质上 是由长度为 m 的位向量或位列表(仅包含 0 或 1 位值的列表)组成,最初所有的值均设置为 0。
3.2、添加数据
当我们向布隆过滤器中添加数据时,为了尽量地址不冲突,会使用多个 hash 函数对 key 进行运算,算得一个下标索引值,然后对位数组长度进行取模运算得到一个位置,每个 hash 函数都会算得一个不同的位置。再把位数组的这几个位置都置为 1 就完成添加操作。
3.3、判断是否存在
向布隆过滤器查询某个key是否存在时,先把这个 key 通过相同的多个 hash 函数进行运算,查看对应的位置是否都为 1,只要有一个位为零,那么说明布隆过滤器中这个 key 不存在;如果这几个位置全都是 1,那么说明极有可能存在;因为这些位置的 1 可能是因为其他的 key 存在导致的,也就是前面说过的hash冲突。
注:使用时不要让元素个数大于bit数组大小。
4、使用场景
4.1、缓存穿透
一般情况下,先查询缓存redis是否有该条数据,缓存中没有时,再查询数据库。当数据库也不存在该条数据时,每次查询都要访问数据库,这就是缓存穿透。缓存透带来的问题是,当有大量请求查询数据库不存在的数据时,就会给数据库带来压力,甚至会拖垮数据库,可以使用布隆过滤器解决缓存穿透的问题。
布隆过滤器使用 Redis 的 bitmap 数据结构实现。
把已存在数据的key存在布隆过滤器中,相当于redis前面挡着一个布隆过滤器。当有新的请求时,先到布隆过滤器中查询是否存在:如果布隆过滤器中不存在该条数据则直接返回;如果布隆过滤器中已存在,才去查询缓存redis,如果redis里没查询到则再查询Mysql数据库。
注:布隆过滤器主要是筛选出指定的key存不存在,还可以用于黑名单过滤,安全网址过滤等场景。
5、布隆过滤器的优缺点
优点:高效插入和查询,内存占用bit空间小。
缺点:1)、不能删除元素;2)、存在一定的误判率。
6、布隆过滤器使用
# 1、使用bitmap,将要判断的key计算的hash值对应位置设置为1
setbit key hash值 1
# 2、判断是否存在
getbit key hash值 # 如果为1可能存在,如果不为1,就一定不存在
7、总结
本文详细介绍布隆过滤器的原理以及优缺点,结合Redis的bitmap数据结构使用能够实现布隆过滤器,帮助大家深入理解布隆过滤器。
本人是一个从小白自学计算机技术,对运维、后端、各种中间件技术、大数据等有一定的学习心得,想获取自学总结资料(pdf版本)或者希望共同学习,关注微信公众号:it自学社团。后台回复相应技术名称/技术点即可获得。(本人学习宗旨:学会了就要免费分享)