高并發緩存策略大揭秘:面試必備的緩存更新模式解析
在高并發場景中,緩存能抵擋大量數據庫查詢,減少數據庫壓力,對于緩存更新通常有以下幾種模式可以選擇:
? cache aside
? read/write through
? write behind caching
cache aside模式
Cache-aside模式是一種常用的用于管理緩存的模式。它用于確保緩存與底層數據源之間的數據一致性。以下是cache-aside模式的工作原理:
圖片
1. 從緩存讀取:當有讀取操作請求時,應用程序首先檢查緩存中是否存在數據。如果在緩存中找到了數據,則將其返回給調用者,避免了訪問底層數據源的需要。
2. 緩存未命中:如果在緩存中未找到數據,則表示緩存未命中。在這種情況下,應用程序從底層數據源檢索數據,并將檢索到的數據填充到緩存中。
3. 更新數據:當對數據執行寫入或更新操作時,應用程序首先更新底層數據源中的數據。然后,清除緩存中的數據,以確保下一次讀取從數據源中檢索到更新后的數據。
通常寫緩存和寫數據庫是兩個獨立的事務,選擇先更新緩存還是先更新數據庫都有可能產生數據不一致的情況。
先刪緩存,再更新數據庫的問題
假設有兩個請求A、B。
? 請求A先刪除緩存,此時還未更新數據庫
? 請求B查詢緩存未命中,然后查詢數據庫,查出舊數據寫入緩存
? 請求A繼續將數據寫入數據庫
? 此時緩存與數據庫中的數據出現了不一致的情況
將緩存更新不做刪除的問題
? 請求A先更新了數據庫
? 請求B更新了數據庫,并更新了緩存
? 請求A最后更新緩存,此時請求A的數據是臟數據。
先更新DB再失效緩存問題
先更新DB,再失效緩存也會出現問題。
? 請求A讀取緩存未命中,查詢數據庫成功查到數據
? 請求B進來更新數據庫成功,并刪除緩存數據
? 請求A將查詢的數據寫入到緩存中,此時請求A寫入緩存的數據已經是臟數據
read/write through模式
cache aside模式需要應用方維護緩存的讀寫,對數據和緩存的維護設計侵入代碼,代碼復雜性增加。read/write through模式彌補了這一問題,調用方無需管理緩存和數據庫調用,通過抽象緩存管理組件維護緩存和數據庫的讀寫,解耦業務代碼。
read through模式
當客戶端請求一個數據時,如果緩存中不存在該項(緩存未命中),緩存系統會自動從后端存儲中加載數據,然后將其添加到緩存中,并返回給客戶端。對于后續的相同請求,數據則直接從緩存中獲取,直到緩存過期或被淘汰。
圖片
write through模式
在write-through模式中,當客戶端更新一個數據項時,緩存系統會同時更新緩存和后端存儲。這意味著所有的寫操作都會同步地寫入緩存和存儲,確保二者的數據一致性。
圖片
write behind caching模式
Write Behind模式和Write Through模式整個架構是一樣的,核心在于write through在緩存數據庫中的更新是同步的,而Write Behind是異步的。
每次的請求寫都是直接更新緩存然后就成功返回,并沒有同步把數據更新到數據庫。而把更新到數據庫的過程稱為flush,觸發flush的條件可自定義,如定時或達到一定容量閾值時進行flush操作。并且可以實現批量寫,合并寫等策略,也有效減少了更新數據的頻率,這種模式最大的好處就是讀寫響應非常快,吞吐量也會明顯提升。這種模式也有其他的問題,比如數據不是強一致性的,因為把最新的數據放在緩存里,如果緩存在flush到數據庫之前宕機了就會丟失數據,另外實現也比較復雜。
幾種模式對
模式 | 優點 | 缺點 |
Cache Aside | 實現比較簡單 | 需要應用程序負責緩存的讀取和寫入操作,代碼侵入較大 |
Read/Write Through | 引入緩存管理組件,緩存和數據庫的維護對應用程序透明;應用代碼入侵小,邏輯更清晰 | 引入緩存管理組件,實現更復雜 |
Write Behind Caching | 讀寫直接和緩存交互,異步批量更新數據 |