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

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

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

相关推荐
PGCCC17 分钟前
【PGCCC】postgresql 缓存池并发设计
数据库·缓存·postgresql
小爬虫程序猿23 分钟前
如何利用Python解析API返回的数据结构?
数据结构·数据库·python
wowocpp1 小时前
查看 磁盘文件系统格式 linux ubuntu blkid ext4
linux·数据库·ubuntu
Ai 编码助手7 小时前
MySQL中distinct与group by之间的性能进行比较
数据库·mysql
陈燚_重生之又为程序员7 小时前
基于梧桐数据库的实时数据分析解决方案
数据库·数据挖掘·数据分析
caridle7 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
白云如幻7 小时前
MySQL排序查询
数据库·mysql
萧鼎7 小时前
Python并发编程库:Asyncio的异步编程实战
开发语言·数据库·python·异步
^velpro^7 小时前
数据库连接池的创建
java·开发语言·数据库
荒川之神7 小时前
ORACLE _11G_R2_ASM 常用命令
数据库·oracle