布隆过滤器

布隆过滤器

检索元素是否存在大集合中

判断不存在的key,一定不存在;判断存在的key,有可能不存在

优点:插入、查询速度快、占用空间小、保密性好(存储的都是0和1)

缺点:很难进行删除操作、误判(误判率可设置)

原理

就是计算数据的哈希值、再由哈希值映射到数组的下标

存入、查询

对你好进行多个哈希计算,计算出对应的下标:比如,3、5、7。

如果是存入,就将对应的下标的值改为1

如果是查询,那3、5、7中只要有一个不是1,那该数据就不在布隆过滤器存在

删除

当你好和hello通过哈希,计算出的下标都是2时,如果想删除你好的数据。就也会把hello的删掉

Java模拟



import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;

/**
 * @date 2023/3/5 下午2:54
 * 布隆过滤器
 */
public class Test {


    /**
     * 长度
     */
    private static int size = 1000000;

    /**
     * 误判率
     */
    private static  double fpp = 0.01;

    /**
     * 布隆过滤器
     */
    private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(),size,fpp);

    // 测试布隆过滤器误判率
    public static void main(String[] args) {

        // 先给布隆过滤器放百万条数据
        for (int i=0;i<1000000;i++){
            bloomFilter.put(i);
        }

        // 测试误判率
        int count = 0;

        for (int i= 1000000;i<1000000+100000;i++){

            if (bloomFilter.mightContain(i)){
                // 误判了
                count++;
            }

        }
        System.out.println("总共误判次数:" + count);


    }

}

尝试后,误判率还真是:0.01

总结:

误判率越小,占用空间大小更大,需要的哈希函数就越多。所以性能就越差

Redis的布隆过滤器


    // redis使用布隆过滤器
    public static void main(String[] args) {

        Config config = new Config();

        // 此处改为连接集群即可
        config.useSingleServer().setAddress("redis:/127.0.0.1:6379");
        config.useSingleServer().setPassword("123456");

        Redissonlient redissonlient = Redisson.create(config);

        // 给布隆过滤器起名字
        RBloomFilter<String> rBloomFilter = redissonlient.getBloomilter("aaa");
        // 大小、误判率
        rBloomFilter.tryInit(1000000L,0.03);

        rBloomFilter.add("12122");

        // 判断下面的是否在布隆过滤器中
        System.out.println(rBloomFilter.contains("21312"));

    }

布谷鸟过滤器(布隆加强版)

未完待续