布隆过滤器

前段时间和小伙伴讨论 redis 在实际生产中的应用,提到了布隆过滤器 。于是做了一些功课。

1 布隆过滤器简介

        布隆过滤器(Bloom Filter)是一个高空间利用率的概率性数据结构,由二进制向量(即位数组)和一系列随机映射函数(即哈希函数)两部分组成。如下所示:

添加元素

        当使用布隆过滤器添加 key 时,会使用不同的 hash 函数对 key 存储的元素值进行哈希计算,从而会得到多个哈希值。根据哈希值计算出一个整数索引值,将该索引值与位数组长度做取余运算,最终得到一个位数组位置,并将该位置的值变为 1。每个 hash 函数都会计算出一个不同的位置,然后把数组中与之对应的位置变为 1。通过上述过程就完成了元素添加(add)操作。

判断元素是否存在

        当我们需要判断一个元素是否存时,其流程如下:首先对给定元素再次执行哈希计算,得到与添加元素时相同的位数组位置,判断所得位置是否都为 1,如果其中有一个为 0,那么说明元素不存在,若都为 1,则说明元素有可能存在。

误判

        那些被置为 1 的位置也可能是由于其他元素的操作而改变的。比如,元素1 和 元素2,这两个元素同时将一个位置变为了 1。在这种情况下,我们就不能判定“元素 1”一定存在,这是布隆过滤器存在误判的根本原因。

2 布隆过滤器使用场景

1 原本有10亿个号码,现在又来了10万个号码,要快速准确判断这10万个号码是否在10亿个号码库中?

2 接触过爬虫的,应该有这么一个需求,需要爬虫的网站千千万万,对于一个新的网站url,我们如何判断这个url我们是否已经爬过了?

3 垃圾邮箱的过滤,黑白名单过滤

4 多用于处理缓存穿透问题

3 布隆过滤器安装与使用

1 docker 安装

docker pull redislabs/rebloom:latest
docker run -p 6379:6379 --name redis-redisbloom redislabs/rebloom:latest
docker exec -it redis-redisbloom bash
redis-cli
#测试是否安装成功
127.0.0.1:6379> bf.add test hello

2 直接编译安装

        建议使用 1.1.1 版本

下载地址:
https://github.com/RedisBloom/RedisBloom/releases/tag/v1.1.1
可以直接下载编译好的 rebloom.so 文件
拷贝至指定目录:
cp rebloom.so /data/redis/conf/
在redis配置文件里加入以下配置:
loadmodule /data/redis/conf/rebloom.so
配置完成后重启redis服务:
#测试是否安装成功
127.0.0.1:6379> bf.add test hello

4 常用命令

命令

说明

bf.add

只能添加元素到布隆过滤器。

bf.exists

判断某个元素是否在于布隆过滤器中。

bf.madd

同时添加多个元素到布隆过滤器。

bf.mexists

同时判断多个元素是否存在于布隆过滤器中。

bf.reserve

以自定义的方式设置布隆过滤器参数值,共有 3 个参数分别是 key、error_rate(错误率)、initial_size(初始大小)。

5 Redission 使用布隆过滤器

/**
 * 操作布隆过滤器
 *
 * @param name
 * @return
 */
public RBloomFilter<String> getBloomFilter(String name) {
    return redissonClient.getBloomFilter(name);
}
@Test
public void testBloomFilter() {
    RBloomFilter<String> demo = component.getBloomFilter("demo");
    demo.tryInit(10000L, 0.01);
    for (int i = 0; i < 10000; i++) {
        demo.add(String.valueOf(i));
    }
    // 误判次数
    int count = 0;
    for (int i = 10000; i < 20000; i++) {
        if (demo.contains(String.valueOf(i))) {
            count++;
        }
    }
    System.out.println(count);
}

        ps:实际操作过程中发现,redisson 并没有使用到布隆过滤器的插件,而是采用 hash 和 string 来实现的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值