Redis缓存穿透之布隆过滤器

缓存穿透场景描述:一般判断用户是否在缓存中,如果存在则直接返回结果,不存在则查询数据库,如果来一波冷数据,会导致缓存大量击穿,造成数据库宕机。

常用解决方法:

  • 缓存空值:将第一次查询的为空的数据也缓存至redis中,并且设置一个过期时间防止redis内存占满
  • 布隆过滤器:布隆过滤器当缓存的索引,只有在布隆过滤器中,才去查询缓存,如果没查询到则穿透到数据库查询。如果不在布隆过滤器中,则直接返回,但是会造成一定程度的误判

什么是布隆过滤器

布隆过滤器(Bloom Filter),是一种非常节省空间的概率数据结构,运行速度快,占用内存小,但是有一定的误判率且无法删除元素。它实际上是一个很长的二进制向量和一系列随机映射函数组成,主要用于判断一个元素是否在一个集合中。

布隆过滤器的优点:

  • 支持海量数据场景下高效判断元素是否存在
  • 布隆过滤器存储空间小,并且节省空间,不存储数据本身,仅存储hash结果取模运算后的位标记
  • 不存储数据本身,比较适合某些保密场景

布隆过滤器的缺点:

  • 不存储数据本身,所以只能添加但不可删除,因为删掉元素会导致误判率增加
  • 由于存在hash碰撞,匹配结果如果是“存在于过滤器中”,实际不一定存在
  • 当容量快满时,hash碰撞的概率变大,插入、查询的错误率也就随之增加了

Java集成Redis使用布隆过滤器

pom中引入redisson依赖:

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

编写代码测试

    public void patchingConsum(ConsumPatchingVO vo) throws ParseException {
        Config config = new Config();
        SingleServerConfig singleServerConfig = config.useSingleServer();
        singleServerConfig.setAddress("redis://127.0.0.1:6379");
        singleServerConfig.setPassword("123456");
        RedissonClient redissonClient = Redisson.create(config);
        RBloomFilter<String> bloom = redissonClient.getBloomFilter("name");
        // 初始化布隆过滤器;  大小:100000,误判率:0.01
        bloom.tryInit(100000L, 0.01);
        // 新增10万条数据
        for(int i=0;i<100000;i++) {
            bloom.add("name" + i);
        }
        // 判断不存在于布隆过滤器中的元素
        List<String> notExistList = new ArrayList<>();
        for(int i=0;i<100000;i++) {
            String str = "name" + i;
            boolean notExist = bloom.contains(str);
            if (notExist) {
                notExistList.add(str);
            }
        }
        if (StringUtils.isNotEmpty(notExistList) && notExistList.size() > 0 ) {
            System.out.println("误判次数:"+notExistList.size());
        }

    }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容