第十节 缓存击穿

一、缓存击穿概念

        缓存击穿是大量的请求同时查询同一个缓存,但是此时缓存突然失效了,那么顺理成章的,这些大量的请求就会去查询数据库。这样的后果是,短时间内数据库会出现大量的查询请求,有可能会让数据库压力过大而宕机。

二、实例代码

        解决办法一:缓存击穿的一大必要条件就是热点数据失效。因此解决办法之一就是把热点数据设置为永不失效

        解决办法二:添加互斥锁。什么意思呢?就是查询同一个热点数据的多组请求,只能有一个请求走数据库,并将查询结果存放到缓存中。接下来的其他的请求会在缓存中查询到此热点数据。

         互斥锁的核心命令就是SETNX命令、expire命令、delete命令。

         (1)生成一个随机数作为锁。获取到锁的线程进入查询数据库的操作。将查询到的数据加入缓存。

         (2)需要设置锁的过期时间,防止不释放锁。

         (3)释放锁的时候,要判断锁是不是当前线程创建的锁,否则很可能释放其他线程创建的锁。


        if (stringRedisService.exists(key)) {
            
                LOGGER.info("返回缓存数据");

        } else {

            LOGGER.info("随机生产一个锁");
            final String value = RandomStringUtils.randomAlphanumeric(10);
            ValueOperations<String,String> valueOperations = 
                                         redisTemplate.opsForValue();
            try{
                LOGGER.info("通过Redis的SETNX命令,查看这个锁是否已经被占用");
                LOGGER.info("如果返回false,说明已经有其他线程进入了,那么此线程放弃操作");
                LOGGER.info("其他线程会在下面的代码中把数据加入到缓存中");
                LOGGER.info("接下来的其他线程会直接走缓存,而不需要走数据库");

               //setNx
               Boolean lock = 
                        valueOperations.setIfAbsent(Constant.USER_RANDOM_KEY,value);

                //如果获取到锁
                if(lock){
                    //设置锁的超时间时间
                    redisTemplate.expire(Constant.USER_RANDOM_KEY,10, TimeUnit.SECONDS);

                    LOGGER.info("从数据库中查询User");

                    LOGGER.info("将数据库中查询到的User加入缓存中");
                    
                    LOGGER.info("因此,接下来的其他的大量的请求就会查询缓存,而不用查询数据库");

                }
            }finally {
                LOGGER.info("释放锁");
                String currentValue = valueOperations.get(Constant.USER_RANDOM_KEY);
                LOGGER.info("判断是不是当前线程创建的锁");
                if(StringUtils.isNotBlank(currentValue) && currentValue.equals(value)){
                    redisTemplate.delete(Constant.USER_RANDOM_KEY);
                }
            }
        }
    }

        参考:第十八节 Redis实现分布式锁

阅读更多 

        跟着大宇学Redis--------目录帖

posted @ 2022-07-17 12:14  小大宇  阅读(28)  评论(0编辑  收藏  举报