zoukankan      html  css  js  c++  java
  • 布隆过滤器实现

    单机版-Guava

    引入guava依赖:

            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <version>31.0.1-jre</version>
            </dependency>
    

    测试:

        @Test
        public void test2() {
            BloomFilter<Integer> filter = BloomFilter.create(Funnels.integerFunnel(), 100);
    
            System.out.println(filter.mightContain(1));
            System.out.println(filter.mightContain(2));
    
            filter.put(1);
            filter.put(2);
    
            System.out.println(filter.mightContain(1));
            System.out.println(filter.mightContain(2));
        }
    

    此外BloomFilter.create方法还可以增加一个误判率的参数,实际guava底层的误判率是0.03

      public static <T extends @Nullable Object> BloomFilter<T> create(
          Funnel<? super T> funnel, long expectedInsertions) {
        return create(funnel, expectedInsertions, 0.03); // FYI, for 3%, we always get 5 hash functions
      }
    

    Guava中的布隆过滤器只能单机使用,现在互联网公司一般都是分布式。

    Redis版布隆过滤器

    布隆过滤器解决缓存穿透的流程图如下:

    image-20211117135824552

    引入redisson依赖:

            <dependency>
                <groupId>org.redisson</groupId>
                <artifactId>redisson</artifactId>
                <version>3.12.5</version>
            </dependency>
    

    布隆过滤器的使用:

    @SpringBootTest
    class RedisApplicationTests {
    
        private static RedissonClient redissonClient;
    
        private static RBloomFilter<Object> bloomFilter;
    
        private static long size = 1000000;
    
        private static double fpp = 0.01;
    
        @BeforeAll
        public static void before() {
            Config config = new Config();
            config.useSingleServer().setAddress("redis://xxx.xxx.xxx.xxx").setDatabase(0).setPassword("xxxxxxxx");
            redissonClient = Redisson.create(config);
            bloomFilter = redissonClient.getBloomFilter("myBloomFilter", new StringCodec());
            bloomFilter.tryInit(size, fpp);
            bloomFilter.add("10000");
        }
    
        @Test
        void contextLoads() {
            Assertions.assertTrue(bloomFilter.contains("10000"));
            Assertions.assertFalse(bloomFilter.contains("10001"));
        }
    }
    

    运行结束后,redis中也会存在布隆过滤器的相关配置:

    image-20211117143049631

    Docker安装RedisBloom

    redis在4.0之后有了插件的功能(Module),可以使用外部的扩展功能,可以使用RedisBloom作为redis布隆过滤器插件。

    此外也可以使用Docker安装RedisBloom。

    docker run -p 6380:6379 -itd --name redis-redisbloom redislabs/rebloom:latest
    

    执行命令:

    docker exec -it redis-redisbloom redis-cli
    
    127.0.0.1:6379> BF.ADD newFilter foo
    (integer) 1
    127.0.0.1:6379> BF.EXISTS newFilter foo
    (integer) 1
    127.0.0.1:6379> BF.EXISTS newFilter foo1
    (integer) 0
    
  • 相关阅读:
    Spring-data-jpa和mybatis的比较及两者的优缺点?
    http和https的区别
    Springboot中spring-data-jpa实现拦截器
    RabbitMQ客户端页面认识
    设计模式之策略模式
    设计模式之策略模式应用实例(Spring Boot 如何干掉 if else)
    设计模式之装饰器模式
    网页跳转小程序
    好帖子
    git 回滚操作
  • 原文地址:https://www.cnblogs.com/wwjj4811/p/15567354.html
Copyright © 2011-2022 走看看