记录一次缓存穿透的经历

在最近的一次需求中,用到了缓存的技术,本以为是很简单的从缓存读取信息而已,没想过造成了缓存穿透的问题,以前也只是听说过缓存穿透,并没有实际遇到过,还好在一次code review中被同事一眼看出,避免了缓存穿透的问题,下面分享给大家

需求

简单的介绍一下我的需求:中间有一段比较重要的逻辑为首先从缓存从获取用户信息,若缓存不存在,则查询DB,最后存至redis

代码

    public String getStr() {
        String str = null;
        str = stringRedisTemplate.opsForValue().get("key");

        // 缓存中存在,则直接返回缓存中的数据
        if (Strings.isNotBlank(str)) {
            return str;
        }

        // 查询DB
        str = findDB("key");
        // 若DB也不存在,说明无数据,返回null
        if (str == null) {
            return null;
        }

        // 存至redis,并返回
        stringRedisTemplate.opsForValue().set("key", str, 1, TimeUnit.DAYS);
        return str;

    }

分析

简单一看好像并没有发现什么问题,但是会导致缓存穿透。因为在查询一个redis和DB都不存在的数据时,那么我每次调用这个方法,我都会走到redis和DB,这对DB来说是不能接受的。

解决

1.缓存null值:即数据库查询不到为null时,也进行缓存,设置一个短时间缓存,保证短时间内多次请求会命中缓存

    public String getStr() {
        String str = null;
        str = stringRedisTemplate.opsForValue().get("key");

        // 缓存中存在,则直接返回缓存中的数据
        if (Strings.isNotBlank(str)) {
            return str;
        }

        // 查询DB
        str = findDB("key");
        // 若DB也不存在,说明无数据,返回null
        if (str == null) {
            stringRedisTemplate.opsForValue().set("key", str, 10, TimeUnit.MINUTES);
            return null;
        }

        // 存至redis,并返回
        stringRedisTemplate.opsForValue().set("key", str, 1, TimeUnit.DAYS);
        return str;

    }

2.布隆过滤器

将数据库中所有的查询条件,放入布隆过滤器中,当一个查询请求过来时,先经过布隆过滤器进行查,如果判断请求查询值存在,则继续查;如果判断请求查询不存在,直接丢弃

总结

经过这个例子,自己也理解了缓存穿透,希望也能帮助大家

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值