Redis针对缓存击穿的解决方法-互斥锁

参考至:Java岗大厂面试百日冲刺 - 日积月累,每日三题【Day2】 —— Redis篇1_陈哈哈的菜园子-CSDN博客

缓存穿透:指缓存和数据库中都没有的数据,导致所有的请求都打到数据库上,然后数据库还查不到(如null),造成数据库短时间线程数被打满而导致其他服务阻塞,最终导致线上服务不可用,这种情况一般来自黑客同学。

缓存击穿:指缓存中没有但数据库中有的数据(一般是热点数据缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去查,引起数据库压力瞬间增大,线上系统卡住。

缓存雪崩:指缓存同一时间大面积的失效,缓存击穿升级版。

针对缓存击穿的解决方法

1、根据实际业务情况,在Redis中维护一个热点数据表,批量设为永不过期(如top1000),并定时更新top1000数据。
2、加互斥锁(mutex key)


互斥锁
  缓存击穿后,多个线程会同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个互斥锁来锁住它。
  其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后做缓存。后面的线程进来发现已经有缓存了,就直接走缓存。
 

 static Lock reenLock = new ReentrantLock();
    public String findPubConfigByKey1(String key) throws InterruptedException {
        PubConfig result = new PubConfig();
        // 从缓存读取数据
        result = redisService.getObject(PubConfigKeyConstants.TABLE_NAME + "_"+key, PubConfig.class) ;
        if (result== null ) {
            if (reenLock.tryLock()) {
                try {
                    System.out.println("拿到锁了,从DB获取数据库后写入缓存");
                    // 从数据库查询数据
                    result = pubConfigRepository.queryPubConfigInfoByKey(key);
                    // 将查询到的数据写入缓存
                    Gson g = new Gson();
                    String value = g.toJson(result);
                    redisService.setNx(PubConfigKeyConstants.TABLE_NAME + "_"+key, value);
                } finally {
                    reenLock.unlock();// 释放锁
                }

            } else {
                // 先查一下缓存
                result = redisService.getObject(PubConfigKeyConstants.TABLE_NAME + "_"+key, PubConfig.class) ;
                if (result== null) {
                    System.out.println("我没拿到锁,缓存也没数据,先小憩一下");
                    Thread.sleep(100);// 小憩一会儿
                    return findPubConfigByKey1(key);// 重试
                }
            }
        }
        return result.getValue();
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值