缓存穿透解决方案:布隆过滤器

BitSet基础

我们会遇到这样的需求,在海量数据中找出某个数据,我们想要的就是BitSet,BitSet本质是一个bit数组,使用1表示存在,0表示不存在。

简单使用示例:

 BitSet bitSet = new BitSet(10);# 数组大小10
        bitSet.set(1); # 索引1,记1
        bitSet.set(2); # 索引2,记1
        System.out.println(bitSet.get(1212));# 索引1212,没有数据,所以为0
        System.out.println(bitSet.get(1));# 索引1,值为1,表示存在

BitSet占用空间小,1G的空间,可以表示85亿的不同数,所以广泛应用于大数据处理。

当然,BitSet也有不好的地方,

  1. 当数据分布不均匀,BitSet造成空间浪费。比如1,2,999,存入bitSet的时候,需要初始化BitSet空间为999,有效位置只有3个,其他都被浪费。
  2. BitSet只面向数字,且是正数,其他类型需要转为int类型,但是转换的时间也难免出现重复,BitSet准确率则降低。

所以,guava的BloomFilter诞生了,它就是bitSet的增强版本。

BloomFilter布隆过滤器

话不多说,使用起来很方便,如下:

  • 引入google的guava pom
 <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
     <version>19.0</version>
  </dependency>
  • 实现代码
BloomFilter blackListIps = BloomFilter.create(Funnels.stringFunnel(Charset.forName("utf-8")),10000);
        blackListIps.put("192.168.2.1");
        blackListIps.put("192.168.2.3");
        blackListIps.put("192.168.3.3");

        System.out.println(blackListIps.mightContain("192.168.2.1"));
        System.out.println(blackListIps.mightContain("192.168.4.1"));

应用

  • 缓存穿透

在使用缓存时候,需要注意很多的坑,其中黑客利用不存在的key去进行缓存穿透,很容易将DB打爆,BloomFilter就可以派上用场了,在每次查询redis之前加个BloomFilter,看是否存在key,没有则直接返回空,防止无效请求到db。

  • 推荐内容去重
  • 爬虫URL判重
  • 垃圾邮件过滤
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值