redis中使用bloomfilter的白名单功能解决缓存穿透问题

一 缓存预热

1.1 缓存预热

将需要的数据提前缓存到缓存redis中,可以在服务启动时候,或者在使用前一天完成数据的同步等操作。保证后续能够正常使用。

1.2 缓存穿透

在redis中,查询redis缓存数据没有内容,接着查询mysql数据库,也没有需要的内容,做了两次无用的查询。进而造成mysql数据库的负担,造成一系列的风险。

解决办法:bloomfilter+白名单实现过滤。

1.3 白名单的作用

白名单里面有才让允许通过,没有的内容则不允许通过。但是存在误判的情况,比如bloomfilter中存在查询的内容且允许通过,但是并不是我们真正需要的那个内容。

1.4 白名单入门案例

复制代码
public class WhiteList {
    public static void main(String[] args) {
        testGuavaWithBloomFilter();
    }
    public static void testGuavaWithBloomFilter()
    {
        //1 创建guava版布隆过滤器
        BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), 100);

        //2 判断指定的元素是否存在
        System.out.println(bloomFilter.mightContain(1));
        System.out.println(bloomFilter.mightContain(2));

        System.out.println();

        //3 讲元素新增进入bloomfilter
        bloomFilter.put(1);
        bloomFilter.put(2);
        System.out.println(bloomFilter.mightContain(1));
        System.out.println(bloomFilter.mightContain(2));

    }
}

结果:

1.5 白名单+过滤器的实现案例

逻辑: guava布隆过滤器插入100万样本数据并额外10W测试是否存在,这10w的数据在100w的数据可能存在相同的情况,存储到相同位置。比如规则为m%3,则 1,4,7放到同一个位置槽中。

1.5.1 代码逻辑

1.controller

复制代码
@RestController
@Slf4j
public class GuvaFilter {
    @Resource
    private GuavaBloomFilterService guavaBloomFilterService;

    @ApiOperation("guava布隆过滤器插入100万样本数据并额外10W测试是否存在")
    @RequestMapping(value = "/guavafilter",method = RequestMethod.GET)
    public void guavaBloomFilter()
    {
        guavaBloomFilterService.guavaBloomFilter();
    }
}

2.service

复制代码
@Service
@Slf4j
public class GuavaBloomFilterService
{
    //1 定义一个常量
    public static final int _1W = 10000;
    //2 定义我们guava布隆过滤器,初始容量
    public static final int SIZE = 100 * _1W;
    //3 误判率,它越小误判的个数也就越少(思考,是否可以是无限小??没有误判岂不是更好)
    public static double fpp = 0.01;//0.01 0.000000000000001
    //4 创建guava布隆过滤器
    private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), SIZE,fpp);


    public void guavaBloomFilter()
    {
        //1 先让bloomFilter加入100W白名单数据
        for (int i = 1; i <= SIZE  ; i++) {
            bloomFilter.put(i);
        }
        //2 故意取10W个不在合法范围内的数据,来进行误判率的演示
        ArrayList<Integer> list = new ArrayList<>(10 * _1W);

        //3 验证
        for (int i = SIZE+1; i <= SIZE+(10 * _1W) ; i++)
        {
            if(bloomFilter.mightContain(i))
            {
                log.info("被误判了:{}",i);
                list.add(i);
            }
        }
        log.info("误判总数量:{}",list.size());
    }
}

3.截图

控制台打印日志:

1.7 bloomfilter总结

bloomfilter作用:查询的内容A,一定不存在,在过滤器中查询肯定没有;如果存在,但是存在误判的情况,但是误判率很小,可以忽略。

1.7 黑名单的使用

黑名单:在黑名单的存在的内容,就不再推荐;不存在则推荐。

应用案例: 抖音等媒体的推荐内容。

相关推荐
q***518922 分钟前
离线安装 Nginx
运维·数据库·nginx
R.lin40 分钟前
memcached 的核心工作机制、优缺点、适用场景以及常见问题的处理方式
数据库·缓存·memcached
醉风塘1 小时前
MongoDB Docker 镜像制作与部署指南
数据库·mongodb·docker
羑悻的小杀马特1 小时前
openGauss 应用开发测评(PostgreSQL 接入方式)
数据库·postgresql·opengauss
bug总结1 小时前
更新原生小程序封装(新增缓存订阅)完美解决
前端·缓存·小程序
Alex艾力的IT数字空间1 小时前
完整事务性能瓶颈分析案例:支付系统事务雪崩优化
开发语言·数据结构·数据库·分布式·算法·中间件·php
wangchen_02 小时前
MySQL复合查询
数据库·mysql
hygge9992 小时前
MySQL 全体系深度解析(存储引擎、事务、日志、MVCC、锁、索引、执行计划、复制、调优)
数据库·经验分享·mysql·adb·面试
百***65953 小时前
PON架构(全光网络)
网络·数据库·架构
笃行客从不躺平3 小时前
CPU 缓存 高并发探索
缓存