緩存與數據庫的一致性

參考文章 http://www.javashuo.com/article/p-qadiunjd-dt.html數據庫

緩存與數據庫的一致性

緩存適用於讀多寫少的場景,而且能極大地提高性能和效率;可是讓緩存的數據與數據庫保持一致是一個難題緩存

保持一致的策略

  1. 當數據更新時,先更新緩存,若是緩存更新成功,再更新數據庫
    • 適用場景有限,且實現起來較爲複雜(若是數據庫操做失敗,要進行補償措施,對緩存數據進行還原)
  2. 當數據更新時,先刪除緩存,若是緩存刪除成功,再更新數據庫
    • 適用全部的場景,且實現起來簡單,是最經常使用的

存在的問題

不考慮策略1,如下將深刻探究策略2併發

在高併發的狀況下,假設請求1(更新操做)先刪除緩存,再更新數據庫,若是請求2(讀操做)在緩存刪除與數據庫更新之間進行了讀取數據,就會讀入舊數據到緩存,待數據庫更新後,此時舊數據緩存與數據庫發生不一致的現象負載均衡

該問題的核心是,請求1的操做不能被其餘請求打斷,而且請求1與其餘請求之間要保持有序(串行執行)。遇到這種狀況,能夠採用隊列的方式去解決(爲了保證串行執行,工做線程只能有1個),當出現更新請求時,直接將其丟進隊列,等待異步執行;當出現讀請求時,先讀緩存,成功則返回,若是緩存不存在,再去判斷隊列頭部是不是同一條記錄的更新請求,若是是,爲了避免打斷其操做,將讀請求也丟進隊列,而後同步等待緩存更新完成;若是不是,說明該更新請求早已完成,直接讀數據庫並緩存便可,不要入隊列。異步

優化

  1. 隊列能夠建立多個,運用Hash法將不一樣記錄的請求散列到不一樣的隊列,能夠負載均衡,並行執行,也能夠避免堵塞
  2. 在分佈式場景下,隊列最好共享
  3. 進入隊列的讀請求能夠採用超時等待,一旦超時,直接讀數據庫並返回,避免長時間的不響應

最後強調:只有讀多寫少的場景才用緩存!!!讀多寫少、讀多寫少,其餘狀況不要用

相關文章
相關標籤/搜索