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
    
  • 相关阅读:
    POJ 1401 Factorial
    POJ 2407 Relatives(欧拉函数)
    POJ 1730 Perfect Pth Powers(唯一分解定理)
    POJ 2262 Goldbach's Conjecture(Eratosthenes筛法)
    POJ 2551 Ones
    POJ 1163 The Triangle
    POJ 3356 AGTC
    POJ 2192 Zipper
    POJ 1080 Human Gene Functions
    POJ 1159 Palindrome(最长公共子序列)
  • 原文地址:https://www.cnblogs.com/wwjj4811/p/15567354.html
Copyright © 2011-2022 走看看