Redis布隆过滤器 Redisson 汇总
一、Redis 布隆过滤器与 Redisson 简介
布隆过滤器(Bloom Filter)是一种概率型数据结构,用于快速判断一个元素 “是否存在于集合中”。它的特点是:
- 优点:空间效率极高(远小于传统集合)、查询速度快(O (k),k 为哈希函数数量);
- 缺点:存在误判率(可能把 “不存在的元素” 判断为 “存在”),且一般不支持删除元素。
Redis 本身没有内置布隆过滤器,但可通过第三方模块(如 RedisBloom)或客户端实现。Redisson是 Redis 的 Java 客户端,内置了布隆过滤器的实现,简化了在 Java 项目中使用 Redis 布隆过滤器的流程。
二、Redisson 中布隆过滤器的使用步骤
1. 引入依赖
在 Maven 项目中添加 Redisson 依赖(版本根据实际需求选择):
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.23.3</version>
</dependency>
2. 配置 Redisson 客户端
初始化 Redisson 连接(以单机 Redis 为例):
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
public class RedissonConfig {
public static RedissonClient getRedissonClient() {
Config config = new Config();
// 连接单机Redis(实际环境需替换为真实地址和密码)
config.useSingleServer()
.setAddress("redis://127.0.0.1:6379")
.setPassword("your-password") // 无密码可省略
.setDatabase(0); // 选择数据库
return Redisson.create(config);
}
}
3. 使用布隆过滤器
核心操作:初始化(设置预期容量和误判率)、添加元素、判断元素是否存在。
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
public class BloomFilterDemo {
public static void main(String[] args) {
// 获取Redisson客户端
RedissonClient redissonClient = RedissonConfig.getRedissonClient();
// 1. 获取布隆过滤器实例(指定名称,确保唯一)
RBloomFilter<String> bloomFilter = redissonClient.getBloomFilter("user:ids");
// 2. 初始化:设置预期元素数量和误判率
// 预期元素数:100万,误判率:0.01(1%)
bloomFilter.tryInit(1_000_000, 0.01);
// 3. 向过滤器添加元素
bloomFilter.add("user1001");
bloomFilter.add("user1002");
bloomFilter.add("user1003");
// 4. 判断元素是否存在
System.out.println(bloomFilter.contains("user1001")); // true(一定存在)
System.out.println(bloomFilter.contains("user9999")); // false(一定不存在)
System.out.println(bloomFilter.contains("user2000")); // 可能为true(误判)
// 关闭客户端
redissonClient.shutdown();
}
}
关键参数说明
- 预期元素数(expectedInsertions):预估需要存入的元素总量,值越准确,空间利用率越高。
- 误判率(falseProbability):允许的误判概率(如 0.01 表示 1%),值越小,需要的哈希函数和存储空间越多(空间与误判率成反比)。
三、适合的场景
布隆过滤器适合 “需要快速判断元素是否存在,且可容忍低概率误判” 的场景,典型包括:
1. 缓存穿透防护(最常用)
- 问题:当请求一个 “不存在的 key” 时,缓存(Redis)不命中,会直接穿透到数据库,若有大量此类请求,会压垮数据库。
- 解决:用布隆过滤器预存所有 “存在的 key”(如数据库中的用户 ID、商品 ID)。请求时先查布隆过滤器:
- 若过滤器判断 “不存在”,直接返回空(无需查缓存和数据库);
- 若判断 “可能存在”,再查缓存→数据库(即使误判,也只会偶尔穿透,影响极小)。
2. 海量数据去重
- 例如:爬虫去重(判断 URL 是否已爬取)、日志去重(判断某条日志是否已处理)。
- 优势:相比用 HashSet 存储,布隆过滤器占用空间极小(例如 100 万 URL,误判率 1%,仅需约 1.5MB 空间)。
3. 防止重复操作
- 例如:限制用户重复点击按钮(如 “点赞”“下单”)、防止消息重复消费。
- 原理:将已处理的操作 ID 存入布隆过滤器,新操作先判断 ID 是否存在,避免重复执行。
4. 垃圾邮件 / 恶意 URL 过滤
- 用布隆过滤器存储已知的垃圾邮件地址或恶意 URL,新邮件 / URL 先通过过滤器快速判断,再进一步处理(误判的正常内容可人工审核)。
四、解决的核心问题
- 空间效率问题:相比传统集合(如 Redis 的 Set),布隆过滤器用极小的空间存储海量元素(无需存储元素本身,仅存储哈希标记)。
- 查询性能问题:O (k) 的查询速度,远快于遍历或复杂索引查询,适合高并发场景。
- 缓存穿透问题:通过预先拦截 “不存在的 key”,避免大量无效请求穿透到数据库,保护后端服务。
五、局限性
- 误判率:无法 100% 准确判断元素是否存在,可能将 “不存在的元素” 误判为 “存在”(但不会漏判,即 “存在的元素一定能被判断为存在”)。
- 不支持删除:传统布隆过滤器无法删除元素(删除会影响其他元素的判断),RedisBloom 模块支持 “计数布隆过滤器”(可删除,但空间开销更大)。
- 初始化依赖预估:预期元素数和误判率需提前设置,若实际数据远超预期,误判率会大幅上升。
总结
Redisson 简化了 Redis 布隆过滤器的使用,其核心价值是用极小空间和快速查询解决 “元素存在性判断” 问题,尤其适合缓存穿透防护、海量数据去重等场景。使用时需根据业务容忍度设置合理的误判率,并注意其局限性。
郭慕荣博客园