Redis布隆过滤器实现检索亿级数据存在

本文介绍了布隆过滤器作为一种节省空间、速度快的数据结构,用于高效判断元素是否存在,探讨其优点(空间效率、保密场景)、缺点(误判率、不可删除)以及在Redis中的应用实例。对比传统方法,布隆过滤器在处理大数据场景中具有明显优势。
摘要由CSDN通过智能技术生成

1、什么是布隆过滤器

布隆过滤器(Bloom Filter)是 1970 年由布隆提出的,是一种非常节省空间的概率数据结构,运行速度快,占用内存小,但是有一定的误判率且无法删除元素。它实际上是一个很长的二进制向量和一系列随机映射函数组成,主要用于判断一个元素是否在一个集合中。

通常我们都会遇到判断一个元素是否在某个集合中的业务场景,这个时候我们可能都是采用 HashMap的Put方法或者其他集合将数据保存起来,然后进行比较确定,但是如果元素很多的情况下,采用这种方式就会非常浪费空间,最终达到瓶颈,检索速度也会越来越慢,这时布隆过滤器(Bloom Filter)就应运而生了。

1.1 布隆过滤器的优点:

  • 支持海量数据场景下高效判断元素是否存在

  • 布隆过滤器存储空间小,并且节省空间,不存储数据本身,仅存储hash结果取模运算后的位标记

  • 不存储数据本身,比较适合某些保密场景

1.2 布隆过滤器的缺点:

  • 不存储数据本身,所以只能添加但不可删除,因为删掉元素会导致误判率增加

  • 由于存在hash碰撞,匹配结果如果是“存在于过滤器中”,实际不一定存在

  • 当容量快满时,hash碰撞的概率变大,插入、查询的错误率也就随之增加了

  • 布隆过滤器中一个元素如果判断结果为存在的时候元素不一定存在,但是判断结果为不存在的时候则一定不存在。因此,布隆过滤器不适合那些对结果必须精准的应用场景。

1.3 其他问题

  • 不支持计数,同一个元素可以多次插入,但效果和插入一次相同

  • 由于错误率影响hash函数的数量,当hash函数越多,每次插入、查询需做的hash操作就越多

2、布隆过滤器原理

布隆过滤器是由一个固定大小的二进制向量或者位图(bitmap)和一系列映射函数组成的。位数组中的每个元素都只占用 1 bit ,并且数组中元素只能是 0 或者 1。这样申请一个 100w 个元素的位数组只占用 1000000Bit / 8 = 125000 Byte = 125000/1024 KB ≈ 122KB 的空间。

image-20231130091621236

2.1 添加元素

通过多个hash函数,算出一个值,然后将这个值所在的方格置为1

2.2 查找元素

通过几个哈希函数分别算出各个值,然后看其对应的地方是否都是1,如果存在一个不是1的情况,该新数据一定不存在于这个布隆过滤器中。

由于多个不同的数据通过hash函数算出来的结果是会有重复的,会存在某个位置是别的数据通过hash函数置为的1,所以不一定能判定该元素一定存在,存在一定的误判率。

2.3 不能删除元素

布隆过滤器通常不支持从集合中删除元素,因为删除一个元素会影响其他元素的哈希值,增加了误判率。

注:布隆过滤器可以判断某个数据一定不存在,但是无法判断一定存在

3、Redis布隆过滤器的实践

Google开源的Guava自带布隆过滤器不支持分布式场景,因此本文采用Redisson 来构造布隆过滤器。

    public void bloom(){
        RBloomFilter<Object> bloomFilter = redissonClient.getBloomFilter("sample");
        //初始化布隆过滤器,长度为55000000,误判率为0.03
        bloomFilter.tryInit(55000000L, 0.03);
        //将数据插入布隆过滤器
        bloomFilter.add(1);
        bloomFilter.add(2);
        bloomFilter.add("Tony");
        bloomFilter.add("Tom");
        //判断元素是否存在
        boolean contains = bloomFilter.contains("Tony");
        //布隆过滤器中元素个数
        long count = bloomFilter.count();
        System.out.println(contains);
        System.out.println(count);
    }

控制台输出结果

image-20231130093032833

4、总结

想要实现10亿的数据中快速判断某一个数据是否存在,使用sql查询会造成数据库性能、负载的问题,如若将数据存到缓存中,一个数据假设是20字节,10亿数据就是20G内存,这个方案内存占用过大。相比之下0.001容错率的布隆过滤器的内存占用为1.67G,既解决了内存问题,又解决了数据库资源使用问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis布隆过滤器Redis Bloom Filter)是一种基于概率数据结构的空间效率高、查询效率快的数据过滤器。它主要用于判断一个元素是否存在于一个大型集合中,具有低内存消耗和快速查询的特点。 布隆过滤器的原理是利用多个哈希函数和一个位数组来表示集合中的元素。当一个元素被加入到布隆过滤器中时,会通过多个哈希函数计算出多个哈希值,并将对应的位数组位置设为1。当需要判断一个元素是否存在时,同样通过多个哈希函数计算出多个哈希值,并检查对应的位数组位置是否都为1。如果有任何一个位置为0,则可以确定该元素不存在于集合中;如果所有位置都为1,则可能存在于集合中,但并不确定。 Redis布隆过滤器通过提供以下几个命令来实现: 1. BF.ADD:将一个元素添加到布隆过滤器中。 2. BF.EXISTS:判断一个元素是否存在布隆过滤器中。 3. BF.MADD:批量添加多个元素到布隆过滤器中。 4. BF.MEXISTS:批量判断多个元素是否存在布隆过滤器中。 需要注意的是,布隆过滤器在判断元素存在时可能会出现误判,即判断元素存在但实际上不存在。这是因为布隆过滤器的位数组中可能存在碰撞,多个元素计算得到的位数组位置可能相同。因此,在使用布隆过滤器时需要权衡误判率和内存消耗之间的关系,并根据具体场景进行调整。 Redis布隆过滤器可以应用于一些需要快速判断元素是否存在的场景,例如缓存穿透的防护、URL去重、爬虫过滤等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值