布隆过滤器

布隆过滤器:

常用场景:

布隆过滤器的常用场景一般是需要判断某一个元素是否存在于一个集合中。他是redis的一种数据结构,但是它和 Redis 内置的 String、Hash、List、Set、ZSet 等"基础数据结构"不是同一类东西。它是通过RBloomFilter进行创建。它可以判断某个元素一定不存在或者可能存在---判断不存在则一定不存在,判断存在则可能不存在。这一特性可以提升很多唯一性判断问题的性能。

判断原理:

布隆过滤器是由一个位数组和一组哈希函数组成。位数组的初始值全部置为 0。在插入一个元素时,将该元素经过多个哈希函数映射到位数组上的多个位置,并将这些位置的值置为 1。哈希函数的个数和设置的误判率有关,错误率越低,位数组越长,布隆过滤器的内存占用越大,散列 Hash 函数越多,计算耗时较长。在插入一个元素时,将该元素经过多个哈希函数映射到位数组上的多个位置,并将这些位置的值置为 1。在查询一个元素是否存在时,会将该元素经过多个哈希函数映射到位数组上的多个位置,如果所有位置的值都为 1,则认为元素存在;如果存在任一位置的值为 0,则认为元素不存在。

优缺点:

优点:

● 高效地判断一个元素是否属于一个大规模集合。

● 节省内存。(不直接存储元素,是通过位数组进行计算判断的)

缺点:

● 可能存在一定的误判(判断不存在则一定不存在,判断存在可能不存在)

使用流程:

1、引入 Redisson(Redis客户端) 依赖

java 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
</dependency>

2、配置Redis参数---application.yaml

java 复制代码
spring:
  data:
    redis:
      host: 127.0.0.1
      port: 6379
      password: 123456

3、设置布隆过滤器配置类

java 复制代码
@Bean
public RBloomFilter<String> userRegisterCachePenetrationBloomFilter(RedissonClient redissonClient) {
    // 1. 获取分布式布隆过滤器实例
    RBloomFilter<String> cachePenetrationBloomFilter = redissonClient.getBloomFilter("userRegisterCachePenetrationBloomFilter");
    // 2. 初始化布隆过滤器(预期1亿元素,0.1%误判率)
    cachePenetrationBloomFilter.tryInit(100000000L, 0.001);
    // 3. 返回过滤器实例,注册为Spring Bean
    return cachePenetrationBloomFilter;
}

4、代码中使用---直接注入:

java 复制代码
private final RBloomFilter<String> rBloomFilter;

使用布隆过滤器的风险与解决方案:

布隆过滤器的拦截能力仅覆盖 "针对已存在数据的查询请求":当请求查询的是已存入布隆过滤器的存量数据时,可被有效拦截;而当攻击者针对某一不存在的目标数据(如未注册的用户名、未生成的短链接码),在极短时间(毫秒级)内发起海量恶意查询请求时,这类请求无法被布隆过滤器识别和拦截,会全部穿透至数据库层。此类海量请求会造成数据库的访问 QPS 骤增,资源占用率瞬间达到瓶颈,最终可能导致数据库服务过载宕机,引发整个业务链路的瘫痪。解决恶意请求的问题,加分布式锁,为每一个未注册的数据加一个分布式锁。但是如果恶意请求全部是使用不存在的数据发起请求,则是防不胜防,只能通过风控系统进行限流保障系统安全。

为何不使用set结构:

有人说为什么不使用Redis中的Set 结构来进行判断是否已经存在,如果使用set结构,那就要持久化存储所有元素,会需要消耗大量的内存,如果是使用的布隆过滤器就不用存储全部的数据,只是根据哈希函数进行映射,对内存要求远低于set结构。

分布式锁和布隆过滤器实现唯一性约束:

分布式锁是具有看门狗机制的,众多请求中只放一个请求访问数据库来保证数据库数据的唯一性约束。但是使用分布式锁实现唯一性的话就会让系统成为串行系统,会影响系统的吞吐量,如果使用布隆过滤器则是并行系统,性能上是优于分布式锁的,大概评估布隆过滤器是分布式锁的 6 倍性能。

布隆过滤器严重缺点:

存入布隆过滤器的数据是无法删除的,如果非要删除,已经删除的短链接我们可以加一层 Set 缓存,彻底删除的数据可以加入到这个 Set 集合中。如果判断在布隆过滤器中存在,需要再去判断是否在 Set 集合,如果set中存在就证明短链接可用,可以进行新增使用。优点是可以满足删除短链接后的复用问题,缺点是需要进行多次网络查询,以及删除要维护多个数据。也可以使用新出的布谷鸟过滤器,但是布谷鸟过于复杂,代码维护成本高。

相关推荐
juniperhan4 分钟前
Flink 系列第21篇:Flink SQL 函数与 UDF 全解读:类型推导、开发要点与 Module 扩展
java·大数据·数据仓库·分布式·sql·flink
ID_180079054736 分钟前
Python 实现亚马逊商品详情 API 数据准确性校验(极简可用 + JSON 参考)
java·python·json
devpotato16 分钟前
Spring Boot mTLS 报 `keystore password was incorrect`:不一定是密码错了
spring boot·tls·pkcs12·mtls
c++之路25 分钟前
C++23概述
java·c++·c++23
专注API从业者1 小时前
Open Claw 京东商品监控选品实战:一键抓取、实时监控、高效选品
java·服务器·数据库
摇滚侠2 小时前
DBeaver 导入数据库 导入 SQL 文件 MySQL 备份恢复
java·数据库·mysql
keep one's resolveY2 小时前
SpringBoot实现重试机制的四种方案
java·spring boot·后端
天空属于哈夫克33 小时前
企业微信API常见的错误和解决方案
java·数据库·企业微信
摇滚侠3 小时前
VMvare 虚拟机 Oracle19c 安装步骤,远程连接 Oracle19c,百度网盘安装包
java·oracle
梁萌3 小时前
idea报错找不到XX包的解决方法
java·intellij-idea·启动报错·缺少包