面试时别只说会redis get set 布隆过滤器了解下

布隆过滤器是一种空间效率极高的概率型数据结构,用于判断一个元素是否在一个集合中。它通过多个哈希函数将元素映射到一个位数组中,可能存在误判但节省空间。在大数据量查询时,可防止数据库压力过大,适用于缓存穿透场景。然而,由于不能准确删除和存在一定误判率,需权衡使用。常见应用包括数据库查询优化、垃圾邮件过滤等。

布隆过滤器是什么

名字就跟每个定律一样,你问为什么叫牛顿定律,因为是牛顿发明或者发现的。「瞪眼」

他能做什么?它是将一个二进制向量和函数映射,布隆过滤器可以用在检测元素是否存在某个集合或者用于快速检索中。

缺点: 有一定的删除问题和错误识别率

优点:查询时间和空间都远远超过普通算法

布隆过滤器Bloom Filter 是怎么实现的

添加Item或者元素时,创建一个散列函数和一个KEY形成映射,设置的数据=1,只要检索时判断 =1就知道这个数据存不存在,有了此方法,查询时发现有0的则证明一定不存在,那么反过来讲如果是1证明元素很可能存在,

注意这里为什么说很可能存在,因为他有一定的识别错误,但这个错误在实际生产过程中可以忽略,毕竟利大于弊么。

看文字晕晕乎乎,不动就画图,来看看应该就会明白许多。

布隆过滤器

全局鸟瞰图

说人话

布隆过滤器到底能干啥?

特殊的id暂且不提哈,数据库id基本都是自增的对吧!我们传递id后端去DB查询,这个非常合理。

但是如果我们用负数查询呢?一两条无所谓,如果成千上万呢?基本上数据库都会很大压力扛不住,服务器配置暂且不说,拖慢系统运行速度甚至宕机都是有可能的,这样是不是布隆过滤器的有点有展现的淋漓尽致。【狗头】

这么吊,也是有代价的,因为它也拿不准,存在一定程度的判断失误!

问:为什么会误判?

答:搜索的key没在容器中,但是hash后得到的key都是1 。假如布隆过滤器中有黑名单,那么直接创建一个白名单就搞定了。

问:为什么不容易删除?

答:我们提到正确的数据Key值=1,但不能因为=0就删掉他,这可能会影响其他元素的判断 不过可以了解下Counting Bloom Filter 「下一篇文章」

说了这么多咋实现

1:预估数量n以及期望的误判率FPP

2: hash函数和bit集合的size大小

Bit集合Size大小

函数 哈希选择,预估值n和bit数组长度m获取hash函数Key

怎么用?maven项目中添加

 <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>23.0</version>
 </dependency>    



一段我写的测试代码

/**
 * 布隆过滤器 - 用于redis缓存穿透 的情况
 * @author 作者 西北大粽子
 */
public class TestBloomFilterByDZZ {

    private static int total = 19999;
    private static BloomFilter<Integer> bfilter = BloomFilter.create(Funnels.integerFunnel(), total);

  // 初始化数据
    public static void main(String[] args) {
        for (int i = 0; i < total; i++) {
            bfilter.put(i);
        }

        // 是否有匹配不上的
        for (int i = 0; i < total; i++) {
            if (!bfilter.mightContain(i)) {
                System.out.println("有没关注西北大粽子的 溜了。。。");
            }
        }

        // 不再内的有多少匹配出来
        int count = 0;
        for (int i = total; i < total + 10000; i++) {
            if (bfilter.mightContain(i)) {
                count++;
            }
        }
        System.out.println("炮灰陪跑:" + count);
    }

}

可适用的业务场景

1:当一个入库数据量比较大的时候,可以用作名称或者唯一件做检查,存在则跳过不存在则入库

2:过滤垃圾邮件,这是一段计算你可以结合自己的业务了解下。

日常求关注,素质一键三连。

每周至少3篇原创文章,在被业务折磨的情况下还能留下点什么。

最近很喜欢的一句话 “有道无术,术尚可求。有术无道,止于术。”

求关注

### 布隆过滤器Redis中的实现 布隆过滤器是一种空间效率极高的概率型数据结构,主要用于测试一个元素是否属于某个集合。其核心在于通过多个哈希函数将元素映射到位数组的不同位置上[^1]。 #### 实现方式一:利用Redis的Bitmap特性 Redis 的 Bitmap 提供了一种高效的方式来存储大量的布尔值(0 或 1),这正是构建布隆过滤器所需的位数组所必需的功能之一。为了实现布隆过滤器: - **初始化**:创建一个新的键名表示布隆过滤器,并将其对应的 bitmap 初始化为空。 - **插入操作**:对于每一个待加入的数据项,应用一组预定义好的哈希函数计算出若干个索引位置,在这些位置处将 bit 设置为 1。 - **查询操作**:当需要判断某条记录是否存在,同样按照上述方法得到相应的索引列表;只要有一个位置上的 bit 是 0 就明该元素不在当前集合内;反之如果所有指定的位置都已经是 1 则认为可能存在此元素(注意这里存在一定的假阳性几率)。 ```python import hashlib import redis class BloomFilter(object): def __init__(self, size=8 * (2 ** 20), hash_count=5): # 默认大小约为1MB self.size = size self.hash_count = hash_count self.bit_array = bytearray(size // 8) pool = redis.ConnectionPool(host='localhost', port=6379, db=0) self.redis_client = redis.Redis(connection_pool=pool) @staticmethod def _get_hash_functions(): """获取多种不同的散列算法""" return [ lambda data: int(hashlib.md5(data).hexdigest(), base=16), lambda data: int(hashlib.sha1(data).hexdigest(), base=16), lambda data: int(hashlib.sha224(data).hexdigest(), base=16), lambda data: int(hashlib.sha256(data).hexdigest(), base=16), lambda data: int(hashlib.sha512(data).hexdigest(), base=16)] def add(self, item): hashes = set() for func in self._get_hash_functions()[:self.hash_count]: index = func(item.encode('utf-8')) % self.size hashes.add(index) pipe = self.redis_client.pipeline() for h in hashes: pipe.setbit("bloomfilter", h, True) pipe.execute() def check(self, item): result = [] for func in self._get_hash_functions()[:self.hash_count]: index = func(item.encode('utf-8')) % self.size result.append(self.redis_client.getbit("bloomfilter", index)) return all(result) bf = BloomFilter() bf.add("example_item") print(bf.check("example_item")) # 输出True print(bf.check("nonexistent_item")) # 输出False ``` 这段Python代码展示了如何使用 Redis 来模拟布隆过滤器的工作流程[^3]。 #### 实现方式二:采用第三方库集成方案 除了手动编码外,还可以考虑直接调用成熟的 Java 库如 Google Guava 中提供的 `com.google.common.hash.BloomFilter` 类来进行更便捷的操作。这种方式下开发者无需关心底层细节,只需关注业务逻辑即可完成快速部署[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

西北大粽子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值