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

文章介绍了缓存预热的重要性,特别是在服务启动时确保数据可用。同时,讨论了缓存穿透问题及其解决方案——使用BloomFilter和白名单策略来避免无效查询对MySQL数据库的压力。BloomFilter虽然存在误判可能,但在控制误判率下能有效过滤数据。文章还提供了Guava实现BloomFilter的代码示例,并探讨了黑名单在内容推荐系统中的应用。
摘要由CSDN通过智能技术生成

一 缓存预热

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 黑名单的使用

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

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

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值