什麼是快取 (Cache)?快取 (Cache) 的機制為何?

2023年2月5日

💎 加入 E+ 成長計畫 如果你喜歡我們的內容,歡迎加入 E+,獲得更多深入的軟體前後端內容

什麼是快取 (Cache)?

目的為了彌補 Database 在複雜業務下的不足,基本原理是將可重使用的資料存放到記憶體中,這樣可以避免每一次都去 Database 讀取,進而將地效能。而以 Memcache 為例,查詢可達到 TPS 50,000 以上。雖然說增加 Cache 可以減輕 Database 的壓力,但會讓系統變得複雜,因此若 Cache 沒有設計好,則有可能造成系統崩潰。

快取 (Cache) 的應用場景

  1. 需要經過複雜計算才能得到值:每一次從 MySQL 去 Count(*) 大量數據,則不管怎麼優化 MySQL 都無法解決這個問題。
  2. 讀多寫少的資料:在 Social media 上,寫的人少(insert)但讀的人多(select),即使 Database 有下 index,但每一個人都去 select 也會大幅降低效能。

快取 (Cache) 設計模式

  1. Cache Aside

    Cache aside
    Cache aside

    Read:優先從 Cache 讀,Cache miss 則從 Database 讀資料,並寫入 Cache,適合讀多的情境

    Write:把資料直接寫入 Database,成功後將 Cache 對應的 key 值設為失效。(不直接寫入 Cache 是為了避免併發問題。)

    注意:還是會有併發問題,一個要讀、另一個要寫時,Cache 很有可能因此存在髒資料。

  2. Read/Write Through

    Cache 作為 Application 與 Database 之間的橋樑,適合寫少讀多的情境,機制如下:

    Read Through, Write Through
    Read Through, Write Through

    Read through: 若 Cache hit 在 Cache 裡則直接回傳,否則從 Database 讀取並同時更新 Cache。

    Write Through: 直接將資料寫入 Cache 以及 Database。

  3. Write behind Cache

    Write behind
    Write behind

    寫操作會直接寫入 Cache,而可依據不同策略決定寫回 Database 的時機,相比於 Write Through 的同步機制,這裡採取非同步的機制,適合寫入多的情境。但要注意若機器當機或 Thread 掛掉,則很有可能丟失資料。

快取 (Cache) 可能的問題

Cache penetration

Cache 並無作用,因此系統依舊還是要去找 Database ,具體可分為以下兩種情境

  1. Database 本來就沒有這筆資料:照理來說這樣發生的請求量應該不大,但如果被惡意攻擊,有可能拖慢整個系統,解法可以是:

    • 當搜尋的 Key 重複率較高時:把相對應個 Key 值給一個 default,這樣下次再被存取時就回傳空值。

    • 當搜尋的 Key 重複率較低時:利用 Bloom filter(類似 hbase 判斷 key 否存在),若存在則去 Cache 或 Database 拿,反之則 return null。

  2. 緩存資料需耗費大量資源與時間:沒辦法把所有商品全部存到 Cache 裡,因此會需要分頁存,因此有可能在訪問時 Cache 會失效,進而 Cache 無法起到作用。

Cache avalanche

若 Key 全部都設同一個 Expire time,則當時間到會同時全部失效,此時會全部像 Database 索取資料,Database 會瞬間壓力過大,解決方法是利用一定區間的隨機值當來當作 Expire time。

Cache breakdown

Cache 失效後引起系統效能急遽下降的情況。例如當 key 值過期後,需要重新和 Database 拿資料,但是在拿資料的過程需要時間,若此時同時有大量訪問需求進來,全部都去 Database 拿資料就會造成問題,因此解法有兩種:

  • 更新鎖:保證只有一個線程可以去更新緩存,其他線程則等待,不過當採分布式集群系統時,多個機器間也會產生緩存雪崩的問題,因此需要用到分布式鎖:Zookeeper

  • 後台更新:由後台線程來更新緩存而非業務線程,具體會將 key 的期限設為永久,並且由後台線程定期清掃。但是當 cache 滿了時就會遇到問題,可能解法為:業務 thread 發現 cache 失效後,通過 message queue 發送一條消息通知後台 thread 更新 cache;或者後台 thread 依據對業務的了解,對於 Key 做定期清洗。

Hotspot cache

雖然 Cache 系統本身的性能比較高,但對於一些特別熱點的數據,如果大部分甚至所有的業務請求都命中同一份 Cache 數據,則這份數據所在的 Cache server 的壓力也很大,解決方法是,複製多份 Cache 副本到多個 Cache server ,減輕 Hotspot cache 導致的單台 Cache server 壓力。

注意:不同的 Cache 副本不要設置統一的過期時間,不然同時失效後可能引發 Cache avalanche。

🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們