參考文章 https://blog.csdn.net/simba_1986/article/details/77823309
緩存與數據庫的一致性
緩存適用於讀多寫少的場景,並且能極大地提升性能和效率;但是讓緩存的數據與數據庫保持一致是一個難題
保持一致的策略
- 當數據更新時,先更新緩存,如果緩存更新成功,再更新數據庫
- 適用場景有限,且實現起來較為復雜(如果數據庫操作失敗,要進行補償措施,對緩存數據進行還原)
- 當數據更新時,先刪除緩存,如果緩存刪除成功,再更新數據庫
- 適用所有的場景,且實現起來簡單,是最常用的
存在的問題
不考慮策略1,以下將深入探究策略2
在高並發的情況下,假設請求1(更新操作)先刪除緩存,再更新數據庫,如果請求2(讀操作)在緩存刪除與數據庫更新之間進行了讀取數據,就會讀入舊數據到緩存,待數據庫更新后,此時舊數據緩存與數據庫發生不一致的現象
該問題的核心是,請求1的操作不能被其他請求打斷,並且請求1與其他請求之間要保持有序(串行執行)。遇到這種情況,可以采用隊列的方式去解決(為了保證串行執行,工作線程只能有1個),當出現更新請求時,直接將其丟進隊列,等待異步執行;當出現讀請求時,先讀緩存,成功則返回,如果緩存不存在,再去判斷隊列頭部是否是同一條記錄的更新請求,如果是,為了不打斷其操作,將讀請求也丟進隊列,然后同步等待緩存更新完成;如果不是,說明該更新請求早已完成,直接讀數據庫並緩存即可,不要入隊列。
優化
- 隊列可以創建多個,運用Hash法將不同記錄的請求散列到不同的隊列,可以負載均衡,並行執行,也可以避免堵塞
- 在分布式場景下,隊列最好共享
- 進入隊列的讀請求可以采用超時等待,一旦超時,直接讀數據庫並返回,避免長時間的不響應