• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    Redis BloomFilter实例讲解

    1. 简介

    布隆过滤器是防止缓存穿透的方案之一。布隆过滤器主要是解决大规模数据下不需要精确过滤的业务场景,如检查垃圾邮件地址,爬虫URL地址去重, 解决缓存穿透问题等。

    布隆过滤器:在一个存在一定数量的集合中过滤一个对应的元素,判断该元素是否一定不在集合中或者可能在集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。

    2. guava 实现

    google的guava工具类已经帮我们造好了轮子,通过实例来感受一下。

    2.1 导入依赖

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

    2.2 BloomFilterTest

    import com.google.common.hash.BloomFilter;
    import com.google.common.hash.Funnels;
    import lombok.extern.slf4j.Slf4j;
    
    /**
     * 布隆过滤器简单实现
     * @author ludangxin
     * @date 2021/8/16
     */
    @Slf4j
    public class BloomFilterTest {
       /**
        * 预计要插入元素个数
        */
       private static final int SIZE = 1000000;
       /**
        * 误判率
        */
       private static final double FPP = 0.01;
       /**
        * 布隆过滤器
        */
       private static final BloomFilterInteger> 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  3000000; i++) {
             if (BLOOMFILTER.mightContain(i)) {
                count++;
                log.info(i + "误判了");
             }
          }
          log.info("总共的误判数:" + count);
       }
    }

    2.3 启动测试

    如上代码,我们设置了0.01的误差,过滤判断时从1000000到3000000,误判了2 * 20000000 ≈ 20339 符合预期。

    .....
    21:40:21.529 [main] INFO com.ldx.redisson.controller.BloomFilterTest - 2999004误判了
    21:40:21.529 [main] INFO com.ldx.redisson.controller.BloomFilterTest - 2999045误判了
    21:40:21.529 [main] INFO com.ldx.redisson.controller.BloomFilterTest - 2999219误判了
    21:40:21.529 [main] INFO com.ldx.redisson.controller.BloomFilterTest - 2999699误判了
    21:40:21.529 [main] INFO com.ldx.redisson.controller.BloomFilterTest - 2999753误判了
    21:40:21.529 [main] INFO com.ldx.redisson.controller.BloomFilterTest - 2999838误判了
    21:40:21.529 [main] INFO com.ldx.redisson.controller.BloomFilterTest - 2999923误判了
    21:40:21.529 [main] INFO com.ldx.redisson.controller.BloomFilterTest - 2999928误判了
    21:40:21.529 [main] INFO com.ldx.redisson.controller.BloomFilterTest - 总共的误判数:20339

    2.4 小节

    guava的工具包虽然好用,但是数据集是存储在jvm中的,分布式环境下依然没法使用。

    3. redisson 实现

    3.1 导入依赖

    dependency>
       groupId>org.redisson/groupId>
       artifactId>redisson-spring-boot-starter/artifactId>
       version>3.16.1/version>
    /dependency>

    3.2 BloomFilterWithRedisson

    import lombok.RequiredArgsConstructor;
    import lombok.extern.slf4j.Slf4j;
    import org.redisson.api.RBloomFilter;
    import org.redisson.api.RedissonClient;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * redisson 布隆过滤器实现
     *
     * @author ludangxin
     * @date 2021/8/16
     */
    @Slf4j
    @RestController
    @RequestMapping("bloomFilter")
    @RequiredArgsConstructor
    public class BloomFilterWithRedisson {
       private final RedissonClient redissonClient;
    
       /**
        * 预计要插入元素个数
        */
       private static final long SIZE = 1000000L;
       /**
        * 误判率
        */
        private static final double FPP = 0.01;
    
       /**
        * 自定义布隆过滤器的 key
        */
       private static final String BLOOM_FILTER_KEY = "bloomFilter";
    
       /**
        * 向布隆过滤器中添加数据, 模拟向布隆过滤器中添加10亿个数据
        */
       @GetMapping
       public void filter() {
         // 获取布隆过滤器
          RBloomFilterInteger> bloomFilter = redissonClient.getBloomFilter(BLOOM_FILTER_KEY);
          // 初始化,容量为100万, 误判率为0.01
          bloomFilter.tryInit(SIZE, FPP);
          // 模拟向布隆过滤器中添加100万个数据
          for (int i = 0; i  SIZE; i++) {
              bloomFilter.add(i);
          }
          int count = 0;
          // 过滤判断
          for (int i = 1000000; i  3000000; i++) {
             if (bloomFilter.contains(i)) {
                count++;
                log.info(i + "误判了");
             }
          }
          log.info("size:" + bloomFilter.getSize());
          log.info("总共的误判数:" + count);
       }
    }

    3.3 启动测试

    由于机器性能有限,又是单机环境,所以程序没有跑完。

    但由此也可以看出,基于redis的布隆过滤器虽然解决了分布式问题,但是性能和guava bloomfilter没法比。

    到此这篇关于Redis BloomFilter实例讲解的文章就介绍到这了,更多相关Redis BloomFilter实例内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    您可能感兴趣的文章:
    • Redis使用元素删除的布隆过滤器来解决缓存穿透问题
    • 布隆过滤器(bloom filter)及php和redis实现布隆过滤器的方法
    • Redis实现布隆过滤器的方法及原理
    • Redis 中的布隆过滤器的实现
    上一篇:为何Redis使用跳表而非红黑树实现SortedSet
    下一篇:详解Redis缓存穿透/击穿/雪崩原理及其解决方案
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    Redis BloomFilter实例讲解 Redis,BloomFilter,实例,讲解,