首页 > 试题广场 >

说一说你对布隆过滤器的理解

[问答题]

说一说你对布隆过滤器的理解

推荐

得分点

​ 布隆过滤器的原理

参考答案

标准回答

​ 布隆过滤器可以用很小的代价来估算出数据是否真实存在,相比于传统的 List、Set、Map 等数据结构,它更高效、占用空间更少,但是缺点是其返回的结果是概率性的,而不是确切的。

​ 布隆过滤器的数据结构是一个大型的位数组,而如果我们要映射一个值到布隆过滤器中,我们还需要使用多个不同的哈希函数来生成多个哈希值,并对每个生成的哈希值指向的位置设置为1。查询key是否存在时,每个哈希函数都利用这个key计算出一个哈希值,再根据哈希值计算一个位置。然后对比这些哈希函数在位数组中对应位置的数值,如果这几个位置中,有一个的位置值为0,则说明过滤器中不存在这个key。如果这几个位置中,所有位置的值都是1,就说明这个布隆过滤器中,极有可能存在这个key。之所以不是百分之百确定,是因为也可能是其他的key运算导致该位置为1。

加分回答

​ 过小的布隆过滤器bit位很快就会都被置为1,那么查询任何值都会返回“可能存在”,这就起不到过滤的目的了。这说明布隆过滤器的长度会直接影响误报率,布隆过滤器越长其误报率越小。

​ 另外,哈希函数的个数也需要权衡,个数越多则布隆过滤器 bit 位置位为 1 的速度越快,且布隆过滤器的效率越低。但是如果太少的话,误报率会变高。

​ 布隆过滤器的典型应用有:

  • 数据库防止穿库。 Google Bigtable,HBase 和 Cassandra 以及 Postgresql 使用BloomFilter来减少不存在的行或列的磁盘查找。避免代价高昂的磁盘查找会大大提高数据库查询操作的性能。
  • 业务场景中判断用户是否阅读过某视频或文章,比如抖音或头条,当然会导致一定的误判,但不会让用户看到重复的内容。
  • 缓存宕机、缓存击穿场景,一般判断用户是否在缓存中,如果在则直接返回结果,不在则查询db,如果来一波冷数据,会导致缓存大量击穿,造成雪崩效应,这时候可以用布隆过滤器当缓存的索引,只有在布隆过滤器中,才去查询缓存,如果没查询到,则穿透到db。如果不在布隆器中,则直接返回。
  • WEB拦截器,如果相同请求则拦截,防止重复被攻击。用户第一次请求,将请求参数放入布隆过滤器中,当第二次请求时,先判断请求参数是否被布隆过滤器命中。可以提高缓存命中率。Squid 网页代理缓存服务器在 cache digests 中就使用了布隆过滤器。Google Chrome浏览器使用了布隆过滤器加速安全浏览服务。
  • Venti 文档存储系统也采用布隆过滤器来检测先前存储的数据。
  • SPIN 模型检测器也使用布隆过滤器在大规模验证问题时跟踪可达状态空间。

​ Redis 因其支持 setbit 和 getbit 操作,且纯内存性能高等特点,因此天然就可以作为布隆过滤器来使用。但是布隆过滤器的不当使用极易产生大 Value这会增加 Redis 阻塞风险,因此实际使用中建议对体积庞大的布隆过滤器进行拆分。拆分的形式方法多种多样,但是本质是不要将 Hash(Key) 之后的请求分散在多个节点的多个小 bitmap 上,而是应该拆分成多个小 bitmap 之后,对一个 Key 的所有哈希函数都落在这一个小 bitmap 上。

延伸阅读

哈希函数的概念:

将任意大小的输入数据转换成特定大小的输出数据的函数,转换后的数据称为哈希值或哈希编码,也叫散列值。

所有散列函数都有如下基本特性:

  • 如果两个散列值是不相同的(根据同一函数),那么这两个散列值的原始输入也是不相同的。这个特性是散列函数具有确定性的结果,具有这种性质的散列函数称为单向散列函数。
  • 散列函数的输入和输出不是唯一对应关系的,如果两个散列值相同,两个输入值很可能是相同的,但也可能不同,这种情况称为“散列碰撞(collision)”。
编辑于 2021-09-15 12:29:55 回复(0)

标准回答

布隆过滤器可以用很小的代价来估算出数据是否真实存在,相比于传统的 List、Set、Map 等数据结构,它更高效、占用空间更少,但是缺点是其返回的结果是概率性的,而不是确切的。

布隆过滤器的数据结构是一个大型的位数组,而如果我们要映射一个值到布隆过滤器中,我们还需要使用多个不同的哈希函数来生成多个哈希值,并对每个生成的哈希值指向的位置设置为1。查询key是否存在时,每个哈希函数都利用这个key计算出一个哈希值,再根据哈希值计算一个位置。然后对比这些哈希函数在位数组中对应位置的数值,如果这几个位置中,有一个的位置值为0,则说明过滤器中不存在这个key。如果这几个位置中,所有位置的值都是1,就说明这个布隆过滤器中,极有可能存在这个key。之所以不是百分之百确定,是因为也可能是其他的key运算导致该位置为1。

加分回答

过小的布隆过滤器bit位很快就会都被置为1,那么查询任何值都会返回“可能存在”,这就起不到过滤的目的了。这说明布隆过滤器的长度会直接影响误报率,布隆过滤器越长其误报率越小。

另外,哈希函数的个数也需要权衡,个数越多则布隆过滤器 bit 位置位为 1 的速度越快,且布隆过滤器的效率越低。但是如果太少的话,误报率会变高。

布隆过滤器的典型应用有:

  • 数据库防止穿库。 Google Bigtable,HBase 和 Cassandra 以及 Postgresql 使用BloomFilter来减少不存在的行或列的磁盘查找。避免代价高昂的磁盘查找会大大提高数据库查询操作的性能。
  • 业务场景中判断用户是否阅读过某视频或文章,比如抖音或头条,当然会导致一定的误判,但不会让用户看到重复的内容。
  • 缓存宕机、缓存击穿场景,一般判断用户是否在缓存中,如果在则直接返回结果,不在则查询db,如果来一波冷数据,会导致缓存大量击穿,造成雪崩效应,这时候可以用布隆过滤器当缓存的索引,只有在布隆过滤器中,才去查询缓存,如果没查询到,则穿透到db。如果不在布隆器中,则直接返回。
  • WEB拦截器,如果相同请求则拦截,防止重复被攻击。用户第一次请求,将请求参数放入布隆过滤器中,当第二次请求时,先判断请求参数是否被布隆过滤器命中。可以提高缓存命中率。Squid 网页代理缓存服务器在 cache digests 中就使用了布隆过滤器。Google Chrome浏览器使用了布隆过滤器加速安全浏览服务。
  • Venti 文档存储系统也采用布隆过滤器来检测先前存储的数据。
  • SPIN 模型检测器也使用布隆过滤器在大规模验证问题时跟踪可达状态空间。

Redis 因其支持 setbit 和 getbit 操作,且纯内存性能高等特点,因此天然就可以作为布隆过滤器来使用。但是布隆过滤器的不当使用极易产生大 Value这会增加 Redis 阻塞风险,因此实际使用中建议对体积庞大的布隆过滤器进行拆分。拆分的形式方法多种多样,但是本质是不要将 Hash(Key) 之后的请求分散在多个节点的多个小 bitmap 上,而是应该拆分成多个小 bitmap 之后,对一个 Key 的所有哈希函数都落在这一个小 bitmap 上。

发表于 2021-11-20 11:28:05 回复(0)
布隆过滤器(Bloom Filter)是一种快速、高效的数据结构,用于判断一个元素是否存在于一个集合中。它基于哈希函数和位数组的原理,可以在空间和时间效率上提供很好的性能。
 布隆过滤器的核心思想是使用多个哈希函数将元素映射到位数组中的多个位置。当一个元素被插入时,将其映射到位数组的多个位置,并将这些位置的值设置为1。当判断一个元素是否存在时,将该元素进行哈希计算,并检查对应的位数组位置的值是否都为1。如果有任何一个位置的值为0,则可以确定该元素不存在于集合中;如果所有位置的值都为1,则可能存在于集合中。
 布隆过滤器的优点包括:
1. 快速查询:布隆过滤器通过多个哈希函数和位数组的映射,可以在常数时间内判断一个元素是否存在,不需要遍历整个集合。
2. 空间效率高:布隆过滤器只需要使用一个位数组和多个哈希函数,占用的空间相对较小。
3. 可扩展性:可以根据需要调整位数组的大小和哈希函数的数量,以满足不同规模的数据集合。
 然而,布隆过滤器也存在一些限制和缺点:
1. 误判率:由于哈希函数的映射可能存在冲突,因此在判断一个元素是否存在时,可能会出现误判的情况,即判断为存在但实际不存在。
2. 不支持删除操作:一旦元素被插入到布隆过滤器中,就无法删除。因为删除一个元素需要将对应的位数组位置设置为0,但这可能会影响到其他元素的判断结果。
3. 需要权衡:在设计布隆过滤器时,需要权衡误判率和空间占用之间的关系,根据实际需求选择适当的参数。
 总的来说,布隆过滤器是一种高效的数据结构,适用于判断一个元素是否存在于一个大规模的集合中,并且对查询速度和空间占用有较高要求的场景。但需要注意其误判率和不支持删除操作的限制。
发表于 2023-06-29 21:02:44 回复(0)
基本概念

布隆过滤器是一种空间效率极高的数据结构,用于快速判断一个元素是否属于一个集合。当我们拿到目标元素时,对元素进行哈希计算,得到多个索引位置,对比索引位置是否都命中,如果有一个不命中,说明该元素不存在于集合中。若全部命中,说明元素可能存在于集合中。
发表于 2024-09-09 15:55:20 回复(0)
布隆过滤器是一种快速高效的数据结构,用于判断一个元素是否存在集合中, 位数组 和hash函数实现的。     优点:快速查询,空间效率高 ,缺点:有一定的误判率,不支持删除操作

发表于 2024-08-09 18:05:38 回复(0)
如果想要判断一个元素是不是在一个集合里,一般想到的是将所有元素保存起来,然后通过比较确定。链表,树等等数据结构都是这种思路. 但是随着集合中元素的增加,我们需要的存储空间越来越大,检索速度也越来越慢(O(n),O(logn))。不过世界上还有一种叫作散列表(又叫哈希表,Hash table)的数据结构。它可以通过一个Hash函数将一个元素映射成一个位阵列(Bit array)中的一个点。这样一来,我们只要看看这个点是不是1就可以知道集合中有没有它了。这就是布隆过滤器的基本思想。
发表于 2022-08-30 10:48:21 回复(0)