高并发架构去重难?架构必备技能 - 布隆过滤器

这篇具有很好参考价值的文章主要介绍了高并发架构去重难?架构必备技能 - 布隆过滤器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系列文章目录

当Dubbo遇到高并发:探究流量控制解决方案
主从选举机制,架构高可用性的不二选择



前言

相信熟悉高并发架构的同学,一定都接触过一个名词————“布隆过滤器”,又或者一些朋友接触其实是在学习Redis的时候,了解到其中有这么一种数据类型。但实际上,除了Redis,在高并发或者各种存储性质的架构中,你经常能见到这种设计的存在,那么今天我们就好好说一说这个布隆过滤器

📕作者简介:战斧,从事金融IT行业,有着多年一线开发、架构及管理经验;爱好广泛,乐于分享,致力于创作更多高质量内容
📗本文收录于 JAVA架构,有需要者,可直接订阅专栏实时获取更新
📘高质量专栏 RabbitMQ、Spring全家桶 等仍在更新,欢迎指导
📙Zookeeper Redis kafka docker netty等诸多框架,以及架构与分布式专题即将上线,敬请期待


一、布隆过滤器简介

布隆过滤器是1970年由布隆(Burton Howard Bloom)提出的概率型数据结构:它通过位数组和哈希函数的巧妙结合它可以快速地判断一个元素是否属于某个集合,而且具有高效的存储和查询。虽然布隆过滤器是概率性的,但其性能却相当出色,尤其在处理大规模数据集时,能够显著减少资源消耗。

如下图:我们预先准备一块bit空间存放位数组,(所谓位数组就是一个数组,数组每个位置就是一个bit大小,只有0和1两种情况)。并定义两种哈希算法H1、H2。然后分别计算Orange 和 Lemon 这两个单词,显而易见的,我们将得到4个值,找到这4个值在bit空间的bit位,将其置为1。这就代表我们存入了Orange 和 Lemon 这两个单词。
必须清楚的一点是:布隆过滤器并不存储数据原文,只存数据经过哈希计算后的得到的位置,所以严格来说它能判重,但并不算容器。当下次再存Orange 或 Lemon的时候,执行上述步骤,我们就能发现对应bit位全为1,则代表数据可能存储过了
高并发架构去重难?架构必备技能 - 布隆过滤器,java架构,架构,Bloom Filter,布隆过滤器,去重,高并发
之所以说可能,是因为可能有别的单词,经过上述H1、H2计算后,落在同样的的两个bit位上,而恰好此时两个bit位都已经被置为1,从而导致误判(如上图的Onion单词)


二、特性与应用场景

其实从上面举得例子,不难总结出布隆过滤器至少有这么几个特性:

  • 快速查询:布隆过滤器具有非常快速的查询操作。无论数据规模多大,查询的时间复杂度都是O(k),其中k是哈希函数的数量

  • 节省空间:相对于其他数据结构,布隆过滤器在存储大规模数据时非常节省空间。它使用位数组来存储数据,而不需要存储实际的元素本身。

  • 概率性判断:布隆过滤器是一个概率性数据结构,意味着在判断一个元素是否存在时,有一定的误判率。如果判断元素不存在,那么它一定不存在;但如果判断元素存在,那么它可能并不存在,因为存在哈希冲突。

  • 元素插入不可逆:一旦将元素插入布隆过滤器,就无法删除或修改该元素。因为删除元素需要将对应的位数组位置置为0,这可能会影响其他元素的判断。

  • 哈希函数的重要性:布隆过滤器的性能和效果与使用的哈希函数密切相关。合理选择和设计哈希函数可以有效降低误判率

结合上述特性,其实我们可以看到布隆过滤器 最适合的场景就是在大数据量下的判重, 因为其速度快、节约空间。虽然可能有“假阳性”(即不存在的数据也判重了)、bit位不可逆的问题,但这些问题通过哈希函数的选择,定好初始bit空间的大小,能很大的程度上的缓解。因此,至今,高并发或重存储的架构下,布隆过滤器,都有着广阔的应用。


三、参数定制

布隆过滤器的大小和哈希函数的个数是根据实际应用场景来确定的,需要平衡误判率和存储空间之间的关系。

一般来说,布隆过滤器的大小是根据预期要处理的数据量和误判率来确定的。误判率越小,需要的空间就越大。哈希函数的个数一般根据预期要处理的数据量和布隆过滤器的大小来确定,一般情况下,哈希函数的个数越多,误判率越小

所以,使用布隆过滤器,有几个方面是我们一开始就要敲定的,就是对未来数据量的预估,以及误差率的限制。我们可以直接给出以下两个公式:

  • m = - (n * ln(p)) / (ln(2)^2)

  • k = (m / n) * ln(2)

其中,m 表示布隆过滤器的大小,k 表示哈希函数的个数,n 表示要处理的数据量,p 表示允许的误差率。我们假设有如下场景:

我们要建立一个网盘产品,为避免一个文件重复存储,预计文件数量将达到20亿条数据,要求在用户上传文件时进行文件判重,误差率要求3%以内。

利用上面的公式:可以计算出:
m = - (20亿 * ln(0.03)) / (ln(2)^2) ≈ 14596881675.7 bits ≈ 1740 MB
k = ( 14596881675.7 / 20亿) * ln(2) ≈ 5.05

因此,可以将布隆过滤器的大小设置为 1740 MB,哈希函数的个数设置为 5个
如果你懒得计算,这里也有一个现成的网站来帮你算: 布隆过滤器参数计算网站 ,可以看到结果是一致的。
高并发架构去重难?架构必备技能 - 布隆过滤器,java架构,架构,Bloom Filter,布隆过滤器,去重,高并发


四、java版本的Demo

我们可以利用JAVA中自带的hashCode函数,和BitSet类来写一个布隆过滤器的Demo

public class BloomFilter<T> {
    private final int size;
    private final BitSet bitSet;

    public BloomFilter(int size) {
        this.size = size;
        this.bitSet = new BitSet(size);
    }

    private int hashFunction1(T value) {
        return Math.abs(value.hashCode()) % size;
    }

    private int hashFunction2(T value) {
        return Math.abs(value.hashCode() / 31) % size;
    }

    public void add(T value) {
        int hash1 = hashFunction1(value);
        int hash2 = hashFunction2(value);
        bitSet.set(hash1);
        bitSet.set(hash2);
    }

    public boolean contains(T value) {
        int hash1 = hashFunction1(value);
        int hash2 = hashFunction2(value);
        return bitSet.get(hash1) && bitSet.get(hash2);
    }
}

再写一个main函数进行验证,结果符合预期。

public static void main(String[] args) {
        BloomFilter<String> bloomFilter = new BloomFilter<>(1000);

        bloomFilter.add("apple");
        bloomFilter.add("banana");

        System.out.println(bloomFilter.contains("apple"));  // Output: true
        System.out.println(bloomFilter.contains("orange")); // Output: false
}

高并发架构去重难?架构必备技能 - 布隆过滤器,java架构,架构,Bloom Filter,布隆过滤器,去重,高并发


五、总结

虽然,我们在第四章使用java写出了一个布隆过滤器的Demo,但显然是不够好的,比如其设计容量得太小,还使用了两个关联的哈希函数。在真实环境中,如果要我们写过滤器,我们还是要严格遵守第三章的公式进行容量和哈希函数的计算。同时哈希函数也应该具有以下几个特点:

  1. 哈希函数需要快速计算,因为布隆过滤器的效率很大程度上依赖于哈希函数的效率
  2. 哈希函数需要输出的哈希值应该尽可能分散、均匀,并且无法推断出输入元素的信息,这样可以使得误判率最小
  3. 哈希函数互相之间应该独立,这样可以保证哈希值之间相互独立,降低误判率

当然,业界也有现成的布隆过滤器供我们使用,比如Google Guava BloomFilter 、Apache Commons Collections BloomFilter 还有很多人熟知的Redis BloomFilter。文章来源地址https://www.toymoban.com/news/detail-620023.html

到了这里,关于高并发架构去重难?架构必备技能 - 布隆过滤器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 位图以及布隆过滤器

    本文主要讲解哈希思想的实际应用,位图和布隆过滤器。 讲解位图之前我们先来解答这样一道腾讯的面试题 给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。【腾讯】 很多人立马就想到了用哈希表或者红黑树,因为足够

    2024年02月08日
    浏览(52)
  • 布隆过滤器的原理

    布隆过滤器是一种用于检索一个元素是否在一个集合中的数据结构,具有高效的查询性能和较小的内存占用。 布隆过滤器的底层实现主要涉及以下几个步骤: 初始化数组: 首先,初始化一个比较大的数组,数组中的元素用二进制表示,初始值都为0。 Hash计算: 当一个新的元

    2024年01月18日
    浏览(38)
  • Redis----布隆过滤器

    目录 背景 解决方案 什么是布隆过滤器 布隆过滤器的原理 一些其他运用 比如我们在观看新闻或者刷微博的时候,会不停地给我们推荐新的内容,我们发现几乎没有重复的,说明后台已经进行了去重处理,基于如何去重,Redis给出了高效的方案---布隆过滤器 1.记录已经浏览过

    2024年02月09日
    浏览(37)
  • 布隆过滤器详解

    本文全部代码地址 布隆过滤器是一种高效的数据结构,用于判断一个元素是否存在于一个集合中.它的主要优点是速度快,空间占用少,因此在需要快速判断某个元素是否在集合中的场合得到广泛引用. 布隆过滤器就是 一个大型的位数组和几个不一样的无偏hash函数. 所谓无偏就是

    2023年04月22日
    浏览(52)
  • Java实现布隆过滤器

    背景: 为预防大量黑客故意发起非法的时间查询请求,造成缓存击穿,建议采用布隆过滤器的方法解决。布隆过滤器通过一个很长的二进制向量和一系列随机映射函数(哈希函数)来记录与识别某个数据是否在一个集合中。如果数据不在集合中,能被识别出来,不需要到数据

    2024年02月01日
    浏览(46)
  • 哈希的应用——布隆过滤器

    上一篇文章,我们学习了位图,位图在某些场景下是非常适用的,非常快捷方便。 但是,在文章的最后,我们也提出了位图的一些缺陷——比如位图只能映射整型数据,其它类型的数据则不行。 因为位图里面的元素去映射的其实就是下标嘛,而下标的话都是整型啊。 那有没

    2024年02月09日
    浏览(41)
  • 布隆过滤器:原理与应用

    本文已收录至GitHub,推荐阅读 👉 Java随想录 微信公众号:Java随想录 原创不易,注重版权。转载请注明原作者和原文链接 目录 布隆过滤器简介 fpp 布隆过滤器原理 布隆过滤器的特点 布隆过滤器使用 布隆过滤器中的数据可不可以删除 布隆过滤器应该设计为多大 布隆过滤器应

    2024年02月08日
    浏览(48)
  • 解释一下布隆过滤器原理

    锁屏面试题百日百刷,每个工作日坚持更新面试题。请看到最后就能获取你想要的,接下来的是今日的面试题: 1.解释一下布隆过滤器原理 在日常生活中,包括在设计计算机软件时,我们经常要判断一个元素是否在一个集合中。比如在字处理软件中,需要检查一个英语单词是

    2023年04月10日
    浏览(47)
  • Redis布隆过滤器原理

    其实布隆过滤器本质上要解决的问题,就是 防止很多没有意义的、恶意的请求穿透Redis(因为Redis中没有数据)直接打入到DB 。它是Redis中的一个 modules ,其实可以理解为一个插件,用来拓展实现额外的功能。 可以简单理解布隆过滤器的功能 :它就是记录了一份DB数据,然后

    2024年02月09日
    浏览(46)
  • 【C++】哈希与布隆过滤器

    🌇个人主页:平凡的小苏 📚学习格言:命运给你一个低的起点,是想看你精彩的翻盘,而不是让你自甘堕落,脚下的路虽然难走,但我还能走,比起向阳而生,我更想尝试逆风翻盘 。 🛸 C++专栏 : C++内功修炼基地 家人们更新不易,你们的👍点赞👍和⭐关注⭐真的对我真

    2024年02月08日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包