当前位置:   article > 正文

布隆过滤器的使用_布隆过滤器使用

布隆过滤器使用

1.场景

我们知道HyperLogLog可以统计pv,uv的个数,其主要用到的两个命令为pfadd,pfcount。没有其他命令去判断是否包含或者是否不包含某个元素。那么会有一种场景,就类似于短视频上的推送视频,怎么做到剔除掉以前已经推送过给用户的短视频了,涉及到一个去重的问题,而在布隆过滤器中有一个exists方法,可以去判断某个元素是否已存在,而且这种方式也很省内存空间,虽说精度存在一点问题,但是这种方式可以去重!

2.布隆过滤器的原理

1.我们知道布隆过滤器的命令主要为bf.add,bf.exits。bf.add和bf.exists的原理是什么呢?

2.布隆过滤器底层其实是用一个大的位数组来存储数据的,对于add进来的元素,比如add了hellojava,hellovue,hello这三个字符串,底层会调用几个hash函数,假设调用了三个hash函数,算出了hellojava对应的hash值为1,6,7,算出hello的hash值为6,7,算出hellovue的hash值为6,7,13。然后再用这几个hash值分别对位数组的长度取模,得到其在位数组上的索引位置,假设这里对位数组长度取模后仍然为原来的值,那么其结果就为如下图所示,1就代表有值,0就代表没有值,bf.exists其就是去判断位数组上某个索引位置是是否为1来判断是否存在的,但是有可能会出现误判,可以看到如下图,hello对应的索引位置上都为1,但是不代表hello这个字符串真实存在!有可能是其它元素hellovue和hellojava它们之中的某一部分而已!
在这里插入图片描述

3. 布隆过滤器安装与启动

1.通过docker安装

docker run -p 6379:6379 --name redis-redisbloom redislabs/rebloom:latest
  • 1
  1. 直接编译安装
cd redis-6.2.5/
wget https://github.com/RedisBloom/RedisBloom/archive/v2.2.5.tar.gz
tar -zxvf v2.2.5.tar.gz 
cd RedisBloom-2.2.5/
make
  • 1
  • 2
  • 3
  • 4
  • 5
  1. 在redis的配置文件,加载redisbloom.so文件

在这里插入图片描述

4.验证是否安装且配置布隆过滤器成功,重启redis,使用bf.add命令测试,返回1代表安装且配置布隆过滤器成功

在这里插入图片描述

4. 布隆过滤器的基本使用

1.bf.add/bf.madd,添加和批量添加
2.bf.exists/bf.mexists,判断是否存在和批量判断
在这里插入图片描述

3.使用jedis操作布隆过滤器
1)加bloom依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>distribute-lock</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--json依赖-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.3</version>
        </dependency>
        <!--jedis依赖-->
        <dependency>
               <groupId>redis.clients</groupId>
               <artifactId>jedis</artifactId>
               <version>3.2.0</version>
               <type>jar</type>
               <scope>compile</scope>
        </dependency>
        <!--bloom依赖-->
        <dependency>
               <groupId>com.redislabs</groupId>
               <artifactId>jrebloom</artifactId>
               <version>1.2.0</version>
        </dependency>
    </dependencies>

</project>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

2)测试

package com.yl;

import io.rebloom.client.Client;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.JedisPool;

public class BloomTest {
    public static void main(String[] args) {
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        //最大空闲数
        config.setMaxIdle(400);
        //最大连接数
        config.setMaxTotal(2000);
        //连接最大等待时间,-1代表没有限制
        config.setMaxWaitMillis(300000);
        /**
         * 配置连接池的地址,端口号,超时时间,密码
         */
       JedisPool jedisPool = new JedisPool(config,"192.168.244.129",6379,30000,"root123");
       //获取连接对象
        Client client = new Client(jedisPool);
        for (int i = 0; i < 10000; i++) {
            client.add("name","yl"+i);
        }
        //判断是否存在,有可能会出现误判
        System.out.println(client.exists("name","yl7"));
        System.out.println(client.exists("name","1111111111111111"));
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

3)结果
在这里插入图片描述

5. 布隆过滤器参数配置

1.默认情况下它的错误率是0.01,默认存储元素的总个数为100,我们可以通过bf.reserve来重新设置这两个参数。

k1代表key,0.000001代表错误率,值越少,越占内存空间,999999代表存储的元素总个数,当实际数量超出这个值时,错误率会上升。

bf.reserve k1 0.000001 999999
  • 1

在这里插入图片描述

6. 布隆过滤的其他使用场景

redis中常见的一个问题,缓存穿透又称缓存击穿,其大概意思就是存在大量一些不存在redis上的key的恶意请求,在redis中找不到数据,然后又去后台数据库查找数据也找不到,请求过多就会导致系统奔溃!

例子:假设我们要查出1亿用户的信息,首先,将它们全放在redis中,显然是不合理,那么我们如何防止缓存穿透的出现呢?

解决方案:1亿用户的信息可以放到布隆过滤器里,每当请求到布隆过滤器时,就用bf.exists方法判断某一个用户是否存在,如果该用户存在,先在redis缓存中查找该用户信息,redis中没有,再去后台数据库查找该用户信息,如果该用户压根就不是真实存在的,就没必要去后台数据库查用户信息了,这样就可以防止大量的恶意请求到后台数据库了!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/859247
推荐阅读
相关标签
  

闽ICP备14008679号