推薦👍:接近100K star 的Java學習/面試指南:JavaGuidegit
看到不少小夥伴簡歷上寫了「熟練使用緩存」,可是被我問到「緩存經常使用的3種讀寫策略」的時候卻一臉懵逼。github
在我看來,形成這個問題的緣由是咱們在學習 Redis 的時候,可能只是簡單了寫一些 Demo,並無去關注緩存的讀寫策略,或者說壓根不知道這回事。面試
可是,搞懂3種常見的緩存讀寫策略對於實際工做中使用緩存以及面試中被問到緩存都是很是有幫助的!數據庫
下面我會簡單介紹一下本身對於這 3 種緩存讀寫策略的理解。緩存
另外,這3 種緩存讀寫策略各有優劣,不存在最佳,須要咱們根據具體的業務場景選擇更適合的。安全
我的能力有限。若是文章有任何須要補充/完善/修改的地方,歡迎在評論區指出,共同進步!——愛大家的 Guide 哥異步
Cache Aside Pattern 是咱們平時使用比較多的一個緩存讀寫模式,比較適合讀請求比較多的場景。分佈式
Cache Aside Pattern 中服務端須要同時維繫 DB 和 cache,而且是以 DB 的結果爲準。ide
下面咱們來看一下這個策略模式下的緩存讀寫步驟。性能
寫 :
簡單畫了一張圖幫助你們理解寫的步驟。
讀 :
簡單畫了一張圖幫助你們理解讀的步驟。
你僅僅瞭解了上面這些內容的話是遠遠不夠的,咱們還要搞懂其中的原理。
好比說面試官極可能會追問:「在寫數據的過程當中,能夠先刪除 cache ,後更新 DB 麼?」
答案: 那確定是不行的!由於這樣可能會形成數據庫(DB)和緩存(Cache)數據不一致的問題。爲何呢?好比說請求1 先寫數據A,請求2隨後讀數據A的話就頗有可能產生數據不一致性的問題。這個過程能夠簡單描述爲:
請求1先把cache中的A數據刪除 -> 請求2從DB中讀取數據->請求1再把DB中的A數據更新。
當你這樣回答以後,面試官可能會緊接着就追問:「在寫數據的過程當中,先更新DB,後刪除cache就沒有問題了麼?」
答案: 理論上來講仍是可能會出現數據不一致性的問題,不過幾率很是小,由於緩存的寫入速度是比數據庫的寫入速度快不少!
好比請求1先讀數據 A,請求2隨後寫數據A,而且數據A不在緩存中的話也有可能產生數據不一致性的問題。這個過程能夠簡單描述爲:
請求1從DB讀數據A->請求2寫更新數據 A 到數據庫並把刪除cache中的A數據->請求1將數據A寫入cache。
如今咱們再來分析一下 Cache Aside Pattern 的缺陷。
缺陷1:首次請求數據必定不在 cache 的問題
解決辦法:能夠將熱點數據能夠提早放入cache 中。
缺陷2:寫操做比較頻繁的話致使cache中的數據會被頻繁被刪除,這樣會影響緩存命中率 。
解決辦法:
Read/Write Through Pattern 中服務端把 cache 視爲主要數據存儲,從中讀取數據並將數據寫入其中。cache 服務負責將此數據讀取和寫入 DB,從而減輕了應用程序的職責。
這種緩存讀寫策略小夥伴們應該也發現了在平時在開發過程當中很是少見。拋去性能方面的影響,大機率是由於咱們常用的分佈式緩存 Redis 並無提供 cache 將數據寫入DB的功能。
寫(Write Through):
簡單畫了一張圖幫助你們理解寫的步驟。
讀(Read Through):
簡單畫了一張圖幫助你們理解讀的步驟。
Read-Through Pattern 實際只是在 Cache-Aside Pattern 之上進行了封裝。在 Cache-Aside Pattern 下,發生讀請求的時候,若是 cache 中不存在對應的數據,是由客戶端本身負責把數據寫入 cache,而 Read Through Pattern 則是 cache 服務本身來寫入緩存的,這對客戶端是透明的。
和 Cache Aside Pattern 同樣, Read-Through Pattern 也有首次請求數據必定再也不 cache 的問題,對於熱點數據能夠提早放入緩存中。
Write Behind Pattern 和 Read/Write Through Pattern 很類似,二者都是由 cache 服務來負責 cache 和 DB 的讀寫。
可是,兩個又有很大的不一樣:Read/Write Through 是同步更新 cache 和 DB,而 Write Behind Caching 則是隻更新緩存,不直接更新 DB,而是改成異步批量的方式來更新 DB。
很明顯,這種方式對數據一致性帶來了更大的挑戰,好比cache數據可能還沒異步更新DB的話,cache服務可能就就掛掉了。
這種策略在咱們平時開發過程當中也很是很是少見,可是不表明它的應用場景少,好比消息隊列中消息的異步寫入磁盤、MySQL 的 InnoDB Buffer Pool 機制都用到了這種策略。
Write Behind Pattern 下 DB 的寫性能很是高,很是適合一些數據常常變化又對數據一致性要求沒那麼高的場景,好比瀏覽量、點贊量。
個人Github地址:Snailclimb - Overview