緩存常見問題總結

一、緩存穿透:大量請求不命中

1.現象:

request請求在cache中未找到數據,直接查找storage

2.原因:

2.1業務代碼自身問題--->在數據庫中未找到數據,進入死循環

2.2惡意攻擊、爬蟲等--->大量不存在數據查找數據庫,進入死循環

3.如何發現:

3.1業務響應時間

3.2業務本身問題

3.3相關指標:總調用數、緩存層命中數、存儲層命中數

4.解決方法

4.1緩存空對象:存儲層返回空對象, 使下次請求直接返回null

①如果是惡意攻擊,需要佔用更多的緩存空間--->緩存設置過期時間

②網絡原因導致,出現緩存層和存儲層數據短期的不一致

4.2布隆過濾器攔截

①位數組(二進制向量);一系列隨機映射函數--->元素通過Hash函數對應位數組

②布隆過濾不存在,數據一定不存在;布隆過濾存在,數據不一定存在

private static final int insertions = 1000000;
public static void main(String[] args) {
    System.out.println("初始化布隆過濾器,大小爲100w,誤判率爲0.03");
    BloomFilter<String> bf = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8), insertions,0.03);
    System.out.println("創建示例集合");
    List<String> list = new ArrayList<>(insertions);
    for (int i = 0; i < insertions; i++) {
        String uuid = UUID.randomUUID().toString();
        bf.put(uuid);
        list.add(uuid);
    }
    System.out.println("開始過濾,1w數據,100個真的,9900個假的");
    int num=0;
    int right=0;
    int wrong=0;
    for (int i = 0; i < 10000; i++) {
        String data = i % 100 == 0 ? list.get(i / 100) : UUID.randomUUID().toString();
        if (bf.mightContain(data)) {
            num++;
            if (list.contains(data)) {
                right++;
            } else {
                wrong++;
            }
        }
    }
    NumberFormat percentFormat = NumberFormat.getPercentInstance();
    percentFormat.setMaximumFractionDigits(2);
    System.out.println("100W中1W數據百分比結果: ");
    System.out.println("布隆認爲存在的:"+num);
    System.out.println("真實存在的:"+right+"\t 正確率"+percentFormat.format((float)right/100));
    System.out.println("不存在的:"+wrong+"\t 誤判率:"+percentFormat.format((float)wrong/10000));
}

二、緩存擊穿:熱點數據集中過期

 

 

三、緩存雪崩:大量數據集中過期

 

 

 

 

 

 

 

 

 

 

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