当前位置: 首页 > news >正文

使用Redission来实现布隆过滤器

简述布隆过滤器

布隆过滤器是一种概率型数据结构,它可以用来判断一个元素是否在一个集合中。我们当时使用的是Redisson实现的布隆过滤器。它的底层原理是,先初始化一个比较大的数组,里面存放的是二进制0或1。一开始都是0,当一个key来了之后,经过3次hash计算,模数组长度找到数据的下标,然后把数组中原来的0改为1。这样,三个数组的位置就能标明一个key的存在。当需要判断一个元素是否存在时,通过相同的哈希函数计算出该元素在位数组上的位置,如果这些位置上的值都为1,则认为该元素可能存在;如果任何一个位置上的值为0,则该元素一定不存在。在缓存穿透的场景中,我们可以将数据库中存在的数据对应的key存入布隆过滤器,当查询一个key时,先通过布隆过滤器判断该key是否存在,如果不存在,直接返回,避免查询数据库。

为什么会产生误判

误判的产生是由于多个不同的元素可能通过哈希函数映射到位数组的相同位置。这种情况称为哈希冲突。由于布隆过滤器使用多个哈希函数,一个元素的每个哈希值都对应位数组中的一个位置,这意味着不同元素的哈希值可能会重叠。

例如,如果两个不同的元素通过哈希函数计算后都映射到位数组的同一个位置,并且这个位置最初是0,那么当第一个元素被添加到布隆过滤器时,该位置会被设置为1。当第二个元素被检查时,由于该位置已经是1,布隆过滤器可能会错误地认为第二个元素也存在于集合中,即使它实际上并不存在。

减少误判的方法

  1. 增加位数组的大小:更大的位数组可以减少哈希冲突的概率,从而降低误判率。

  2. 增加哈希函数的数量:更多的哈希函数可以更均匀地分布元素到位数组中,但也会增加计算成本。

  3. 选择合适的哈希函数:好的哈希函数可以减少冲突的概率。

布隆过滤器怎么更新和删除内容,有实现的思路吗?

布隆过滤器是一种只支持添加元素,理论上不支持删除元素的数据结构,因为它使用多个哈希函数将元素映射到位数组的多个位置,删除一个元素可能会影响其他元素的检查结果。不过,有一些方法可以间接实现删除操作或者更新布隆过滤器的内容。

1. 重新创建布隆过滤器

最简单直接的方法是重新创建一个布隆过滤器,将需要保留的元素重新添加进去。这种方法成本较高,因为它需要重新计算所有保留元素的哈希值并更新位数组。

2. 使用计数器(Counting Bloom Filter)

计数布隆过滤器(Counting Bloom Filter)是布隆过滤器的一种变体,它使用计数数组代替位数组,每个位置存储一个计数值而不是简单的0或1。这样,删除元素时可以将对应位置的计数值减1,而不是直接置为0。这种方法可以支持删除操作,但增加了存储空间和计算复杂度。

使用Redission来实现布隆过滤器的步骤

 1. 添加Redission依赖

<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.15.6</version> <!-- 请检查最新版本 -->
</dependency>

2. 配置Redission

在应用启动时,配置Redisson客户端以连接到Redis服务器:

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;public class RedissonConfig {public static RedissonClient create() {Config config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379"); // Redis服务器地址return Redisson.create(config);}
}

3. 使用Redisson创建和使用布隆过滤器

import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;public class BloomFilterExample {private static final RedissonClient redisson = RedissonConfig.create();public static void main(String[] args) {// 创建布隆过滤器,预计元素数量为1000,误判率为0.03RBloomFilter<String> bloomFilter = redisson.getBloomFilter("myBloomFilter");bloomFilter.tryInit(1000, 0.03);// 添加元素到布隆过滤器bloomFilter.add("key1");bloomFilter.add("key2");// 检查元素是否存在于布隆过滤器boolean exists1 = bloomFilter.contains("key1"); // 应该返回trueboolean exists2 = bloomFilter.contains("key2"); // 应该返回trueboolean exists3 = bloomFilter.contains("key3"); // 可能返回false或true(误判)System.out.println("key1 exists: " + exists1);System.out.println("key2 exists: " + exists2);System.out.println("key3 exists: " + exists3);}
}

4. 处理缓存穿透

在缓存穿透的场景中,使用布隆过滤器来避免不必要的数据库查询

import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;public class CacheService {// 获取Redisson客户端实例,确保已经配置好Redissonprivate static final RedissonClient redisson = RedissonConfig.create();// 使用Redisson创建布隆过滤器,名称为"myBloomFilter"private static final RBloomFilter<String> bloomFilter = redisson.getBloomFilter("myBloomFilter");/*** 获取数据的方法。* 先通过布隆过滤器检查key是否存在,如果不存在则直接返回null。* 如果存在,从数据库查询数据,并在查询到数据后将key添加到布隆过滤器中。* @param key 要查询的key* @return 查询到的数据,如果不存在则返回null*/public String getData(String key) {// 检查布隆过滤器,如果key不存在,则直接返回nullif (!bloomFilter.contains(key)) {return null;}// 从数据库查询数据String data = queryDatabase(key);// 如果查询到数据,且该key尚未在布隆过滤器中,则添加到布隆过滤器if (data != null && !bloomFilter.contains(key)) {bloomFilter.add(key);}return data;}/*** 模拟从数据库查询数据的方法。* 实际应用中,这里应该是数据库查询逻辑。* @param key 要查询的key* @return 查询到的数据*/private String queryDatabase(String key) {// 这里模拟数据库查询,实际应用中应替换为数据库查询逻辑// 假设数据库中存在key对应的数据return "some data for " + key;}
}

相关文章:

  • C++ asio网络编程(8)处理粘包问题
  • Ubuntu---omg又出bug了
  • Python_day29类的装饰器知识点回顾
  • 王树森推荐系统公开课 排序02:Multi-gate Mixture-of-Experts (MMoE)
  • oracle 资源管理器的使用
  • Java IO及Netty框架学习小结
  • 游戏服务器之聊天频道设计
  • YOLOv5目标构建与损失计算
  • C#里与嵌入式系统W5500网络通讯(2)
  • (二十一)Java集合框架源码深度解析
  • 推理大模型与普通大模型的区别是什么?
  • 程序代码篇---ESP32的数据采集
  • Fine-Tuning Llama2 with LoRA
  • imx6ULL从应用程序到驱动程序
  • 【图像处理基石】OpenCV中都有哪些图像增强的工具?
  • 跨平台多用户环境下PDF表单“序列号生成的服务器端方案“
  • 大语言模型上下文长度:发展历程、局限与技术突破
  • INA226 高侧/低侧测量、双向电流/功率监视器,具有I2C兼容接口
  • 数字格式化库 accounting.js的使用说明
  • 什么是时间戳?怎么获取?有什么用
  • “大国重器”、新型反隐身雷达……世界雷达展全面展示尖端装备
  • 九江银行落地首单畜牧业转型金融业务,助推传统农业绿色智能
  • 中科院合肥物质院迎来新一届领导班子:刘建国继续担任院长
  • 台湾关闭最后的核电,岛内担忧“非核家园”缺电、涨电价困局难解
  • 美国失去最后一个AAA评级,资产价格怎么走?美股或将触及天花板
  • 外企聊营商|上海仲裁:化解跨国企业纠纷的“上海路径”