最經典的快取+資料庫讀寫的模式,就是 cache aside pattern。
讀的時候,先讀快取,快取沒有的話,就讀資料庫,然後取出資料後放入快取,同時返回響應。
更新的時候,先更新資料庫,然後再刪除快取。
為什麼是刪除快取,而不是更新快取?
其實刪除快取,而不是更新快取,就是乙個 lazy 計算的思想,不要每次都重新做複雜的計算,不管它會不會用到,而是讓它到需要被使用的時候再重新計算。像 mybatis,hibernate,都有懶載入思想。查詢乙個部門,部門帶了乙個員工的 list,沒有必要說每次查詢部門,都把裡面的 1000 個員工的資料也同時查出來啊。80% 的情況,查這個部門,就只是要訪問這個部門的資訊就可以了。先查部門,同時要訪問裡面的員工,那麼這個時候只有在你要訪問裡面的員工的時候,才會去資料庫裡面查詢 1000 個員工。
這種先更新資料庫再刪快取也會出現資料不一致的情況
先更新資料庫,再刪除快取。如果刪除快取失敗了,那麼會導致資料庫中是新資料,快取中是舊資料,資料就出現了不一致,這還是有問題的
如果是先刪快取再更新資料庫呢
在高併發的情況下也會出現不一致的情況
比如執行緒1先刪除了快取的資料,還沒來得及更新資料庫,此時執行緒2來讀資料,快取裡面沒有,就讀資料庫,然後把資料更新進快取,此時執行緒1開始更新資料庫,此時快取裡面是老資料,資料庫裡面是新資料,出現快取不一致的情況。
解決方案一 延遲雙刪策略
解決方案二 非同步更新快取
說簡單點就是將讀請求和寫請求序列化放進乙個佇列中去,讓他們按順序執行
比如我現在有個更新的請求,我將它放進乙個佇列,開啟乙個非同步的執行緒讓它去消費佇列,我先刪除快取,還沒來得及更新資料庫的時候,來了乙個讀請求,將它放進佇列去,排在更新請求後面,它必須等更新請求操作完後才能執行,此時更新請求繼續更新資料庫,更新資料庫後,讀請求開始操作,先讀快取,快取沒有,然後讀取資料庫,把資料庫的內容寫進快取,此時資料庫和快取還是一致的
快取一致性解決方案
通常為了提公升使用者體驗,專案裡面一些熱點資料我們會把它放入快取裡面,以商品庫存為例我們就可以把商品對應的庫存資料放入redis,查詢資料時先去redis裡面找,沒有找到再訪問資料庫,如果庫存資料有更新就同時去更新redis的快取資料,以此達到減輕資料庫壓力。這種對快取資料的處理看似沒有問題,實際上...
快取與資料庫一致性
此時系統的讀寫流量很小,這個時候所有的讀寫操作都在主庫 此時,從庫的角色只是作為災備。風險分析 從資料一致性的角度來看沒有任何問題,所有讀寫操作都在主庫 隨著業務的前進和流量的激增,會出現大表和資料庫寫入效能下降的問題。我們可以通過分庫的方式,提公升資料庫單機的qps壓下來 通過分表的方式,降低單錶...
資料庫和快取一致性方案
redis儲存快取,mysql儲存資料。快取進行有效期設定。但是更新mysql,不會更新快取。這樣導致快取和資料庫的一致性問題比較長 mysql更新後,進行更新redis快取。查詢的時候先查詢redis快取,如果沒有快取,只查詢資料庫進行更新快取 快取和資料庫不一致性的時間短 cache aside...