首页 > 数据库 >Spring Boot 使用 Redis 实现布隆过滤器,精准过滤 “无效” 请求

Spring Boot 使用 Redis 实现布隆过滤器,精准过滤 “无效” 请求

时间:2025-01-01 11:02:34浏览次数:7  
标签:Spring Redis 布隆 springframework Boot org 过滤器 import

Spring Boot 使用 Redis 实现布隆过滤器,精准过滤 “无效” 请求

在当今高并发的互联网应用场景下,如何高效地对海量数据进行过滤,避免无效请求对系统资源造成浪费,是每一个开发者都需要面对的问题。布隆过滤器(Bloom Filter)作为一种空间效率极高的概率型数据结构,为我们提供了出色的解决方案。而结合 Spring Boot 的便捷开发特性与 Redis 的高性能存储,能够轻松地将布隆过滤器应用到实际项目中,让我们的系统性能得到质的飞跃。接下来,就详细介绍如何在 Spring Boot 项目中利用 Redis 实现布隆过滤器。

一、布隆过滤器简介

布隆过滤器由 Burton Howard Bloom 在 1970 年提出,它本质上是一个长度为 m 的位数组,初始值全部为 0。同时,它拥有 k 个相互独立的哈希函数,这些哈希函数能将任意输入元素均匀地映射到 m 个位置上。

当向布隆过滤器中添加一个元素时,先使用 k 个哈希函数分别对该元素进行计算,得到 k 个哈希值,然后将位数组中对应这 k 个哈希值的位置置为 1。判断一个元素是否在布隆过滤器中时,同样用 k 个哈希函数计算得到 k 个哈希值,查看位数组中对应位置是否都为 1。若有一个位置为 0,则该元素一定不在;若全部为 1,则该元素很可能在(存在一定的误判概率,这是由于哈希碰撞导致的,但可以通过合理设置参数来控制在极低水平)。

正是这种巧妙的设计,使得布隆过滤器在存储海量数据时,占用空间极小,并且查询效率极高,能够快速判断元素的 “大致存在性”,特别适用于如缓存穿透场景下的无效请求过滤、大规模数据去重等任务。

二、准备工作:Spring Boot 与 Redis 集成

  1. 首先,在 Spring Boot 项目的 pom.xml 文件中引入必要的依赖:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

这里引入了 Spring Boot 与 Redis 集成的基础依赖以及用于构建 Web 应用的依赖,确保项目既能与 Redis 交互,又具备对外提供服务的能力。

  1. application.propertiesapplication.yml 配置文件中配置 Redis 连接信息:
spring:
  redis:
    host: localhost
    port: 6379
    password: your_password  # 如果 Redis 设置了密码,填写此处
    database: 0

根据实际使用的 Redis 服务器情况,调整主机名、端口号、密码以及数据库编号等参数,确保 Spring Boot 项目能够顺利连接到 Redis。

三、代码实现:构建基于 Redis 的布隆过滤器

  1. 创建布隆过滤器配置类:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.sentinel.SentinelConfiguration;
import org.springframework.data.redis.sentinel.SentinelConnectionFactory;
import org.springframework.data.redis.sentinel.SentinelRedisTemplate;
import com.google.common.hash.Funnel;
import com.google.common.hash.Hashing;
import io.rebloom.client.Client;

@Configuration
public class BloomFilterConfig {

    // 定义布隆过滤器的哈希函数个数
    private static final int NUM_HASH_FUNCTIONS = 5;
    // 定义布隆过滤器的位数组大小
    private static final int BIT_ARRAY_SIZE = 1000000;

    @Bean
    public Client redisBloomFilterClient(RedisConnectionFactory redisConnectionFactory) {
        return new Client(redisConnectionFactory, "bloom");
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    public Funnel<CharSequence> funnel() {
        return (Funnel<CharSequence>) (from, into) -> into.putString(from, Charsets.UTF_8).writeBytes();
    }

    @Bean
    public io.rebloom.client.BloomFilter bloomFilter(Client redisBloomFilterClient, Funnel<CharSequence> funnel) {
        io.rebloom.client.BloomFilter bloomFilter = redisBloomFilterClient.createFilter("myBloomFilter", BIT_ARRAY_SIZE, NUM_HASH_FUNCTIONS, funnel);
        return bloomFilter;
    }
}

在这个配置类中,我们首先定义了布隆过滤器的关键参数:哈希函数个数和位数组大小,这两个参数需要根据实际业务需求和数据量进行合理调整。然后,通过 Spring 的 @Configuration@Bean 注解,创建了与 Redis 交互的 Client 对象(用于操作 Redis 中的布隆过滤器)、通用的 RedisTemplate 对象(方便后续其他 Redis 操作)以及构建布隆过滤器所需的 Funnel 对象和 io.rebloom.client.BloomFilter 对象。

  1. 编写业务逻辑类,利用布隆过滤器进行数据过滤:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import io.rebloom.client.BloomFilter;

@RestController
public class BloomFilterController {

    @Autowired
    private BloomFilter bloomFilter;

    @GetMapping("/check")
    public String checkData(String data) {
        boolean mightContain = bloomFilter.mightContain(data);
        if (!mightContain) {
            // 如果布隆过滤器判断数据不存在,直接返回,避免后续昂贵的数据库查询等操作
            return "Data not likely to be in the set";
        }
        // 此处可添加进一步的精确查询逻辑,如数据库查询,因为布隆过滤器存在误判可能
        // 假设这里经过精确查询发现数据确实存在
        return "Data is in the set";
    }

    @GetMapping("/add")
    public String addData(String data) {
        bloomFilter.add(data);
        return "Data added successfully";
    }
}

在这个 RestController 类中,我们注入了之前配置好的布隆过滤器。checkData 方法用于接收外部传入的数据,通过布隆过滤器快速判断该数据是否可能存在于集合中,如果判断为不存在,直接返回提示信息,避免不必要的后续操作,节省系统资源;如果判断为可能存在,则可以根据实际业务需求,进行进一步的精确查询(如查询数据库),因为布隆过滤器存在一定误判概率。addData 方法则用于向布隆过滤器中添加数据,以便后续进行过滤判断。

四、测试与验证

启动 Spring Boot 项目后,我们可以使用工具如 Postman 对编写的接口进行测试。

  1. 首先,通过 http://localhost:8080/add 接口添加一些数据到布隆过滤器中,例如发送 POST 请求,请求体中包含数据 “user1”“productA” 等,多次添加不同的数据,模拟实际业务场景下数据的录入过程。
  2. 然后,使用 http://localhost:8080/check 接口来测试过滤效果,发送 GET 请求,查询刚刚添加的数据以及一些未添加的数据。对于已添加的数据,布隆过滤器大概率会判断其存在(由于误判,偶尔可能会判断为不存在,但概率极低);对于未添加的数据,布隆过滤器几乎肯定会判断其不存在,从而有效拦截了无效请求,验证了布隆过滤器的功能。

通过以上步骤,我们成功在 Spring Boot 项目中利用 Redis 实现了布隆过滤器,实现了对数据的高效过滤,提升了系统在高并发场景下的应对能力。在实际应用中,还可以根据项目需求进一步优化布隆过滤器的参数设置、扩展功能,让它更好地服务于我们的系统。希望这篇文章能帮助你掌握这一实用技术,让你的开发之路更加顺畅!

需要注意的是,文中所使用的 io.rebloom.client 相关类来自于 Redis 的 Rebloom 模块扩展,在使用前确保已经正确安装并引入相关依赖。同时,在优化布隆过滤器参数时,可以参考一些数学公式和实际经验,如根据预估的数据集大小和可接受的误判率来精确计算哈希函数个数和位数组大小,以达到最佳的性能平衡。

标签:Spring,Redis,布隆,springframework,Boot,org,过滤器,import
From: https://blog.csdn.net/weixin_43896211/article/details/144852686

相关文章

  • 【Java项目】基于SpringBoot+Vue的宠物救助及领养平台的设计与实现(源码+LW+包运行)
    源码获取:https://download.csdn.net/download/u011832806/90001525基于SpringBoot+Vue的宠物救助及领养平台开发语言:Java数据库:MySQL技术:SpringBoot+MyBatis+Vue.js工具:IDEA/Ecilpse、Navicat、Maven宠物救助及领养平台是一个专注于宠物保护和幸福的在线平台。它致力于......
  • Spring SpEL表达式由浅入深
    标题前言概述功能使用字面值对象属性和方法变量引用#this和#root变量获取类的类型调用对象(类)的方法调用类构造器类型转换运算符赋值运算符条件(关系)表达式三元表达式Elvis操作符逻辑运算instanceof和正则表达式的匹配操作符安全导航操作员数组集合(Array、List......
  • 记 Redisson 报错 attempt to unlock lock, not locked by current thread
    原文:记一次Redisson线上问题→你怎么能释放别人的锁错误信息:attempttounlocklock,notlockedbycurrentthreadbynodeid:b9df1975-5595-42eb-beae-bdc5d67bce49thread-id:52查看日志,找到对应的堆栈信息:Exceptioninthread"thread0"java.lang.IllegalMoni......
  • Spring Boot的maven配置
    使用maven,创建SpringBoot项目,做个记录,避免重复今天早上3小时的浪费时间新版本的配置方法<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:......
  • spring cloud-nacos注册中心入门指南
    注册中心为什么引入注册中心?引入注册中心的主要原因是为了解决微服务架构中服务发现和动态管理的问题。在微服务架构中,服务提供者和消费者之间需要进行远程调用。由于微服务数量众多且动态变化,手动维护服务地址列表不仅效率低下,而且容易出错。注册中心的引入解决了这些问......
  • 成为百万架构师的第一课:设计模式:Spring中的设计模式
    本文原文地址Spring5源码分析一·、Spring中常用的设计模式1.我们通常说的23种经典设计模式:分类设计模式创建型工厂方法(FactoryMethod)、抽象工厂模式(AbstractFacotry)、建造者模式(Builder)、原型模式(Prototype)、单例模式(Singleton)结构型适配器模式(Adapter)、......
  • Spring Boot引起的“堆外内存泄漏”排查及经验总结7
    背景为了更好地实现对项目的管理,我们将组内一个项目迁移到MDP框架(基于SpringBoot),随后我们就发现系统会频繁报出Swap区域使用量过高的异常。笔者被叫去帮忙查看原因,发现配置了4G堆内内存,但是实际使用的物理内存竟然高达7G,确实不正常。JVM参数配置是“-XX:MetaspaceSize=256M-......
  • spring boot迁移计划 第Ⅰ章 --chapter 1. rust hyper 结合rust nacos-client开发naco
    1.toml依赖nacos_rust_client="0.3"local_ipaddress="0.1"2.代码//todo维护实时服务列表,用来在请求到来时选择转发至具体的服务usestd::sync::Arc;uselog::debug;usenacos_rust_client::client::{naming_client::{Instance,InstanceDefaultList......
  • 聊聊Spring中最常用的11个扩展点
    目录前言1.自定义拦截器2.获取Spring容器对象2.1BeanFactoryAware接口2.2ApplicationContextAware接口2.3ApplicationListener接口3.全局异常处理4.类型转换器5.导入配置5.1普通类5.2配置类5.3ImportSelector5.4ImportBeanDefinitionRegistrar6.项目启动......
  • Spring Boot引起的“堆外内存泄漏”排查及经验总结4
    背景为了更好地实现对项目的管理,我们将组内一个项目迁移到MDP框架(基于SpringBoot),随后我们就发现系统会频繁报出Swap区域使用量过高的异常。笔者被叫去帮忙查看原因,发现配置了4G堆内内存,但是实际使用的物理内存竟然高达7G,确实不正常。JVM参数配置是“-XX:MetaspaceSize=256M-......