首頁 > 軟體

Redis處理高並行之布隆過濾器詳解

2022-12-31 14:02:37

前言

隨著我們業務開發越來越來大,並染請求就會越來越多,那麼我們的專案的壓力就會越來越大,基本都會使用快取,除本地快取,還會用到redis快取,但是你以為使用快取就沒啥問題了麼,那肯定不是的,使用了快取又會出現新的問題,比如,快取的key失效導致大量的請求到資料庫,大量的讀請求瞬間到達了資料庫,cpu的使用率爆增,導致資料庫都可能掛掉,這種情況下我們就要考慮使用redis的布隆過濾器了。

快取穿透、擊穿、雪崩

首先我們從快取會出現的幾種問題,來進行分析,在高並行的場景下如果出現這種情況,我們應該如何解決。

正常情況下,我們的web應用會先去請求快取服務,如果快取命中,那麼就去拿快取裡面的資料,返回結果給應用,

快取穿透

快取穿透與快取雪崩和快取擊穿還是不一樣的,雪崩和擊穿的情況下,資料庫的資料都是真正常的,可以去請求資料庫獲取資料,只是快取層出現問題,等待快取恢復了,就會減輕資料庫的壓力。 而快取透不一樣的就是,快取和資料庫都沒有要請求的資料,大量的請求來了,資料庫的壓力很大。

出現情況

  • 資料庫資料被大量清除,導致存取不到
  • 駭客惡意攻擊

常見的解決方案

  • redis快取空值,請求不到的時候返回給應用空值。
  • 使用布隆過濾器,把資料庫的一部分資料hash到布隆過濾器裡,在請求資料庫之前先去布隆過濾器裡篩選到一部分請求,判斷資料是否存在,避免直接去存取資料庫。

快取擊穿

出現情況

  • 大量熱點資料庫過期,導致無法從快取獲取到資料,大量請求資料庫也無法返回書就

解決方案

  • 加鎖,保證同一時間內,只允許有一個執行緒去更新快取,等鎖釋放後在重新去請求快取。
  • 熱點資料不去設定過期時間,如果要設定過期時間,在過期的時候通知後臺去更新快取的過期時間。

快取雪崩

  • 大量快取在同一時間失效,導致大量請求進入資料庫
  • redis故障宕機,導致快取不能使用。

解決方案

  • 同上加鎖
  • 給快取的過期時間加入亂數,保證快取不會在同一時間同時失效。
  • 副本key策略,就是對於一個key,在它的基礎上在設定一個key,它們的value都是一樣的,只不過一個設定過期時間、一個不設定過期時間,相當於給key做了個副本,只不過在更新快取的時候,副本key也是要更新的,避免出現資料不一致的現象。

布隆過濾器 Bloom filter

前面提到過布隆過濾器在請求比較高的時候,可以幫助我們抵擋一部分請求,從而減輕資料庫的壓力,布隆過濾器的資料結構是一個二進位制的bit向量,或者說是一個bit陣列,它相對於list、set、map這些集合,它佔用的空間更少,不足之處處就是返回的結果會有一定概率的誤差。

public static void main(String[] args) {
    int size = 1_000_000;
    BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), size);
    for (int i = 0; i < size; i++) {
        bloomFilter.put(i);
    }
    for (int i = 0; i < size; i++) {
        if (!bloomFilter.mightContain(i)) {
            System.out.println("有漏網之魚");
        }
    }
    List<Integer> list = new ArrayList<>(1000);
    for (int i = size + 10000; i < size + 20000; i++) {
        if (bloomFilter.mightContain(i)) {
            list.add(i);
        }
    }
    System.out.println("有誤差的數量:" + list.size());
}

確實有誤差的數量,但是誤差量不大,追求效率的同時只是犧牲一點誤差了。

總結

加鎖的排隊的場景確實能幫助我們很好的解決快取穿透、擊穿的一些問題,但是效率也是非常低了,因為每個請求都是排隊等待,如果可以接受輕微誤差的話,布隆過濾器的確是個很不錯的選擇,Bloom filter的bitmap的儲存效率確實很高。

以上就是Redis處理高並行之布隆過濾器詳解的詳細內容,更多關於Redis布隆過濾器處理高並行的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com