Redisson_布隆过滤器

应用场景

        去重

Redisson_布隆过滤器_第1张图片

诞生背景

        Java应用一般通过JDK自身提供的HashSet去重,通过contains()方法判断当前元素是否存在于Set中。该方式要求在调用contains()前,已经将数据列表加载到内存中(即该方法基于内存存储实现判断功能)。

        缺点:

        1.满足不了分布式环境下的判重

        2.高并发产生大数据量的情况下,此种方式容易OOM

简介

        布隆过滤器的初始化

        需要设计并构造K个哈希函数及容量大小为N、每个元素初始取值为0的位数组

        往其中添加元素

        当使用布隆过滤器添加 key 时,会使用不同的 hash 函数对 key 存储的元素值进行哈希计算,从而会得到多个哈希值。根据哈希值计算出一个整数索引值,将该索引值与位数组长度做取余运算,最终得到一个位数组位置,并将该位置的值变为 1

        判断元素是否存在及误判原因

        将当前的元素经过K个哈希函数计算得到K个哈希值,然后判断K个哈希值(数组的下标)对应数组中的取值是否为1(若为1则一定存在);反之,则不一定存在。What???
        
误判原因:比如,元素1 和 元素2,这两个元素同时将一个位置变为了 1(如下图所示)。在这种情况下,我们就不能判定“元素 1”一定存在,这是布隆过滤器存在误判的根本原因。

Redisson_布隆过滤器_第2张图片        优缺点分析

        优点在于它不需要开辟额外的内存存储元素,从而节省了存储空间;缺点在于判断元素是否在集合中时,有一定的误判率,并且添加进布隆过滤器的元素是无法删除的,因为位数组的下标是多个元素“共享”的,如果删除的话,很有可能出现“误删”的情况。

代(上)码(菜)

        基本数据类型

    public void testBaseBloom() {

        //定义Redis中的Key
        final String key = "myBloomFilterBaseData";
        //初始化构造数组容量的大小
        Long total = 100L;
        //创建布隆过滤器组件
        RBloomFilter bloomFilter = redissonClient.getBloomFilter(key);
        //初始化布隆过滤器,预计统计元素数量为100,期望误差率为0.01
        bloomFilter.tryInit(total, 0.01);
        //初始化遍历往布隆过滤器添加元素
        for (int i = 1; i <= total; i++) {
            bloomFilter.add(i);
        }
        //检查特定的元素在布隆过滤器中是否存在并打印输出
        log.info("该布隆过滤器是否包含数据1:{}", bloomFilter.contains(1));
        log.info("该布隆过滤器是否包含数据-1:{}", bloomFilter.contains(-1));
        log.info("该布隆过滤器是否包含数据100:{}", bloomFilter.contains(10000));
        log.info("该布隆过滤器是否包含数据100000:{}", bloomFilter.contains(100000));
    }

       

 包装数据类型

    public void testDtoBloom(){
        //定义Redis中的Key
        final String key="myBloomFilterDtoData";
        //创建布隆过滤器组件
        RBloomFilter bloomFilter=redissonClient.getBloomFilter(key);
        //初始化布隆过滤器,预计统计元素数量为1000,期望误差率为0.01
        bloomFilter.tryInit(1000, 0.01);
        //初始化遍历向布隆过滤器中添加对象
        BloomDto dto1=new BloomDto(1, "1");
        BloomDto dto2=new BloomDto(10, "10");
        BloomDto dto3=new BloomDto(100, "100");
        BloomDto dto4=new BloomDto(1000, "1000");
        BloomDto dto5=new BloomDto(10000, "10000");
        //向布隆过滤器中添加对象
        bloomFilter.add(dto1);
        bloomFilter.add(dto2);
        bloomFilter.add(dto3);
        bloomFilter.add(dto4);
        bloomFilter.add(dto5);
        //检查特定的元素在布隆过滤器中是否存在并打印输出
        log.info("该布隆过滤器是否包含数据(1, \"1\"):{}", bloomFilter.contains(new
                BloomDto(1, "1")));
        log.info("该布隆过滤器是否包含数据(100, \"2\"):{}", bloomFilter.contains
                (new BloomDto(100, "2")));
        log.info("该布隆过滤器是否包含数据(1000, \"3\"):{}", bloomFilter.contains
                (new BloomDto(1000, "3")));
        log.info("该布隆过滤器是否包含数据(10000, \"10000\"):{}", bloomFilter.contains
                (new BloomDto(10000, "10000")));
    }

你可能感兴趣的:(Redisson,redis,redisson,布隆过滤器,判重)