首页 > 其他分享 >布隆过滤器

布隆过滤器

时间:2024-10-08 19:47:05浏览次数:5  
标签:元素 布隆 查询 过滤器 BloomFilter id

目录

什么是布隆过滤器

优点

缺点

布隆过滤器适用于以下场景:

使用步骤

依赖

配置类

使用布隆过滤器实现去重功能(使用之前注意加入依赖和配置类)

将数据存储到布隆过滤器中

从布隆过滤器中拿出来进行判断

使用布隆过滤器解决缓存穿透的问题(使用之前注意加入依赖和配置类)


什么是布隆过滤器

布隆过滤器(Bloom Filter)是一种概率型数据结构,用于检测某个元素是否在集合中。其特点是能够快速判断元素是否存在,但可能出现假阳性,即可能错误地报告某元素存在,但绝不会错过实际存在的元素。它通过使用多个哈希函数将元素映射到一个位数组中,当查询时,检查所有相关位是否为1。如果所有位均为1,则元素可能存在;否则,元素肯定不存在。由于其高效性和低空间需求,布隆过滤器常用于大规模数据集的去重和查询优化。

优点

  1. 空间效率高

:布隆过滤器在存储大量数据时,所需的空间相比其他数据结构(如哈希表或集合)要小得多。它使用一个位数组和多个哈希函数来表示集合,从而显著减少了内存占用。

  1. 查询效率高

:查询操作非常快速。布隆过滤器可以在常量时间内(O(k),其中k为哈希函数的数量)判断元素是否可能存在。这个特性使得布隆过滤器特别适合于需要高性能查询的场景。

  1. 不需要存储数据

:布隆过滤器只存储哈希值对应的位信息,而不直接存储元素本身,因此它节省了存储空间。

  1. 支持大规模数据处理

:在需要处理非常大的数据集合(如网络爬虫、大数据处理系统等)时,布隆过滤器的空间效率可以极大地减轻存储压力。

缺点

  1. 假阳性

:布隆过滤器可能错误地报告某个元素存在(即假阳性),这意味着它会告知某个元素可能在集合中,但实际上可能并不存在。假阳性的概率随着元素的增加和布隆过滤器的填满而增加。

  1. 无法删除元素

:标准的布隆过滤器不支持删除操作。一旦一个元素被添加,无法从布隆过滤器中移除它。删除操作会破坏布隆过滤器的准确性,因为这可能会影响到其他元素的查询结果。

  1. 确定假阳性率需要设置参数

:布隆过滤器的性能依赖于正确的参数设置(位数组大小和哈希函数数量)。如果这些参数设置不当,可能会导致较高的假阳性率或者空间浪费。

  1. 无法给出具体元素的存在信息

:布隆过滤器只能判断元素是否可能存在,不能提供有关元素的具体信息或位置。如果需要对元素进行更多的操作(如获取实际数据),布隆过滤器就不适用了。

布隆过滤器的使用场景

布隆过滤器适用于以下场景:

  1. 缓存系统:用于快速检查缓存是否包含某个数据,减少不必要的数据库查询。
  2. 去重:在大规模数据处理中,例如网页爬虫或日志分析,用于避免重复记录。
  3. 网络安全:用于过滤恶意请求或防止垃圾邮件,快速检测是否已知恶意源。
  4. 数据库优化:在大型数据库中使用布隆过滤器加速查询操作,减少对存储的访问。

使用步骤

依赖

<!--        布隆过滤器依赖-->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>27.0.1-jre</version>
</dependency>

配置类

package com.bawei.config;

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.nio.charset.Charset;

/**
 * @author: 作者
 * @create: 2024-07-05 11:02
 * @Description: Spring3.0时代配置类创建对象
 */
@Configuration
public class BloomFilterConfig {

    @Bean
    public BloomFilter<String>   stringBloomFilter(){
        Charset charset = Charset.forName("UTF-8");
        BloomFilter<String> strBloomFilter = BloomFilter.create(Funnels.stringFunnel(charset),1000000, 0.03);
        return strBloomFilter;
    }
    @Bean
    public BloomFilter<Integer>   integerBloomFilter(){

        BloomFilter<Integer>  integerBloomFilter = BloomFilter.create(Funnels.integerFunnel(),1000000, 0.03);
        return integerBloomFilter;
    }
}

使用布隆过滤器实现去重功能(使用之前注意加入依赖和配置类)

将数据存储到布隆过滤器中

@Autowired
private BloomFilter integerBloomFilter;

//循环集合将id存放到布隆过滤器
for (Hospital hos: list) {
    integerBloomFilter.put(hos.getHospitalId());
}

从布隆过滤器中拿出来进行判断

//判断id是否存在
boolean b = integerBloomFilter.mightContain(hospitalId);
if(!b){
    return Result.res(Res.IS_NOT_ID,null);
}

使用布隆过滤器解决缓存穿透的问题(使用之前注意加入依赖和配置类)

查询bloomfilter是否存在id
boolean b = integerBloomFilter.mightContain(id);
if(!b){
    return R.ok(ResultCodeAndMsg.ERROR).msg("id不存在");
}
//1先查缓存
Object o = redisTemplate.opsForValue().get("ar:reader:" + id);
//2 是否命中,如果命中直接返回
if(null!=o){
    return R.ok(ResultCodeAndMsg.AR_GET_SUCCESS,o).msg("id查询成功");
}

//分布式锁===>Redission分布式锁[看门狗]===>lua脚本保证原子性
//如果能设置成功,返回true,加锁成功
Boolean flag = redisTemplate.opsForValue().setIfAbsent("lock:ar:" + id, 1,2, TimeUnit.MINUTES);

if(!flag) { //没有获取锁
    //等待2秒钟
    try {
        Thread.sleep(2000);
        //重新执行方法
        getArById(id);
        return null;
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

}
    //3 未命中查询数据库
Articles articles = articlesMapper.selectById(id);  //3分钟
    //4 存入缓存
redisTemplate.opsForValue().set("ar:reader:" + id, articles);
//手动释放锁
redisTemplate.delete("lock:ar:" + id);

return R.ok(ResultCodeAndMsg.AR_GET_SUCCESS,articles).msg("id查询成功");

标签:元素,布隆,查询,过滤器,BloomFilter,id
From: https://blog.csdn.net/2301_81405087/article/details/142767770

相关文章

  • Redis缓存穿透解决方案之一:布隆过滤器与计数型布隆过滤器概述以及两者在Spring中的使
    布隆过滤器(BloomFilter)和计数型布隆过滤器(CountingBloomFilter)都是高效的概率性数据结构,用于判断某个元素是否在集合中。它们的设计目标是降低内存开销,通过多个哈希函数与位数组的组合,实现快速查询,但允许一定的误判率。文章目录1.布隆过滤器(BloomFilter)1.1原理1.2......
  • JavaWeb之过滤器
    1.过滤器的概念过滤器是JavaServlet规范中定义的组件,用于在请求到达Servlet之前或响应返回客户端之前,对请求或响应进行拦截和处理。过滤器可以实现以下功能:日志记录:记录请求的详细信息,如URI、参数、时间等。身份验证和授权:检查用户是否已登录,是否有权限访问资源。输入输出......
  • springcloud的gateway使用全局过滤器
    全局过滤器是可以做一些统一的事情,比如认证鉴权、日志处理等@ComponentpublicclassLogFilterimplementsGlobalFilter,Ordered{Loggerlog=LoggerFactory.getLogger(this.getClass());@OverridepublicMono<Void>filter(ServerWebExchangeexchange,G......
  • 面试官:项目中如何实现布隆过滤器?
    谈起“布隆过滤器”相信大家都不陌生,它也算日常面试中的常见面试题了。例如,当面试官在问到Redis模块的相关问题时,可能会问到缓存穿透(Redis四大经典问题之一),而缓存穿透的经典解决方案之一,则是“布隆过滤器”。但是,对于布隆过滤器是什么?以及布隆过滤器的实现原理?相信大部分同学......
  • 6.4.3过滤器字符串
    因为OpticStudio记录了它所跟踪的每条光线的历史记录,所以我们可以使用过滤器字符串来轻松地识别满足特定条件的光线。对于一个关于如何使用过滤器字符串的示例,我们可以查看在上一节中加载的“led_model.zmx”文件。在此文件中,对象2表示源体矩形后面的一个反射器。一些光线从这......
  • Redis系列补充:聊聊布隆过滤器(go语言实践篇)
    ★Redis24篇集合1介绍布隆过滤器(BloomFilter)是Redis4.0版本之后提供的新功能,我们一般将它当做插件加载到RedisService服务器中,给Redis提供强大的滤重功能。它是一种概率性数据结构,可用于判断一个元素是否存在于一个集合中。相比较之Set集合的去重功能,布隆过滤器空......
  • [Spring]过滤器
    过滤器Filter作为Java三大器之一,在JavaWeb的使用中有很高的地位。所谓过滤器,就是实现了javax.servlet.Filter接口的服务器端程序。Filter有如下几个用处:在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest。根据需要检查HttpServletRequest,也可以修改HttpSe......
  • Filter 过滤器和 Listener 监听器
    2、开发步骤3、过滤器执行流程4、过滤器生命周期5、过滤器配置问题6、过滤器链(配置多个过滤器)二、Listener监听器1、ServletContextListener接口2、开发步骤一、Filter过滤器============1、概述当访问服务器资源时,Filter过滤器可以将请求拦截下来,完成一些特殊的......
  • 过滤器Filter 与 拦截器Interceptor
    1.Filter过滤器1.1什么是Filter?Filter表示过滤器,是JavaWeb三大组件(Servlet、Filter、Listener)之一。过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能使用了过滤器之后,要想访问web服务器上的资源,必须先经过滤器,过滤器处理完毕之后,才可以访问对应的资源。......
  • Python中使用Redis布隆过滤器
    Python中使用Redis布隆过滤器在Python中使用Redis布隆过滤器,可以利用redis-py库和redis-py-bloom扩展。布隆过滤器是一种空间效率高的概率性数据结构,适合用于判断某个元素是否在集合中。以下是如何在Python中设置和使用Redis布隆过滤器的步骤:安装依赖首先,确保你已经......