(Redis)緩存處理的幾個問題

目錄

目錄

問題一: 緩存穿透

問題二: 緩存擊穿

問題三: 緩存雪崩

測試代碼


問題一: 緩存穿透

說明: 利用redis與mysql數據庫的機制(redis中一旦不存在查詢的ksy, 就訪問mysql), 直接繞過緩存, 訪問myslq, 而製造db的請求壓力;

解決: 將從mysql請求出的空存入redis一定時間;

問題二: 緩存擊穿

說明: 某一熱點key在高併發訪問的情況下, 突然失效, 導致大量的併發直接訪問mysql數據庫的情況;

解決1: 使用redis的分佈式suo解決mysql的訪問壓力問題;

問題三: 緩存雪崩

說明: 緩存時大量的key採用了相同的過期時間, 導致緩存存在某一時刻同時失效, 導致大量訪問db, db崩潰;

解決: 設置不同的失效時間;

測試代碼

 @Override
    public PmsSkuInfo getSkuById(String skuId) {

        PmsSkuInfo pmsSkuInfo = new PmsSkuInfo();
        //1.連接緩存
        Jedis jedis = redisUtil.getJedis();
        System.out.println("jedis:"+jedis);
        //2.查看緩存
        String skuKey = "sku:"+skuId + ":info";
        String skuJson = jedis.get(skuKey);
        //3.如果緩存中沒有, 則查看mysql中(緩存穿透, 雪崩)
        if (StringUtil.isBlank(skuJson)){
            SetParams params = new SetParams().nx().px(10000);
            String OK = jedis.set("sku:"+skuId+":lock","1",params);
            System.out.println("nx加鎖");
            if (StringUtil.isBlank(OK) && OK.equals("OK")){
                System.out.println("從mysql中獲取數據");
                pmsSkuInfo = this.getSkuByIdFromDB(skuId);
                //4.mysql查詢數據保存在redis中
                if (pmsSkuInfo != null){
                    String json = JSON.toJSONString(pmsSkuInfo);
                    jedis.set(skuKey, json);
                    System.out.println("保存到redis");
                }else{
                    //防止穿透
                    jedis.setex(skuKey,60*3,JSON.toJSONString(""));
                }
                //從數據庫獲取到數據之後,接觸鎖
                jedis.decr("sku:"+skuId+":lock");

            }else{
                System.out.println("自旋:"+skuId);
                //自旋
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return getSkuById(skuId);
            }


        }else{
            pmsSkuInfo = JSON.parseObject(skuJson, PmsSkuInfo.class);
            System.out.println("從redis獲取數據");
        }
        jedis.close();
        return pmsSkuInfo;
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章