緩存數據一致性一般是兩種解決方案
雙寫模式
做法順序:先寫數據庫,再寫緩存
並發性的問題:
由於卡頓等原因,導致寫緩存2在最前,寫緩存1在后面就出現了不一致
臟數據問題:
這是暫時性的臟數據問題,但是在數據穩定,緩存過期以后,又能得到最新的正確數據
讀到的最新數據有延遲:最終一致性
失效模式
做法順序:先寫數據庫,在刪除緩存
並發下的問題:
由於網絡或者i/o問題導致第三個請求拿到了數據庫中數據:db-1,此時第二個請求數據庫寫更新db-1->db-2已完成,立刻刪除緩存,第三個請求又將緩存刷新成第一個請求時的數據
還是會出現臟數據問題:最終不一致性
解決方案:
無論是雙寫模式還是失效模式,都會導致緩存的不一致問題。即多個實例同時更新會出事。怎么辦?
- 如果是用戶緯度數據(訂單數據、用戶數據),這種並發幾率非常小,不用考慮這個問題,緩存數據加 上過期時間,每隔一段時間觸發讀的主動更新即可
- 如果是菜單,商品介紹等基礎數據,也可以去使用canal訂閱binlog的方式(比較優秀)。
- 緩存數據+過期時間也足夠解決大部分業務對於緩存的要求。
- 通過加鎖保證並發讀寫,寫寫的時候按順序排好隊。讀讀無所謂。所以適合使用讀寫鎖。(業務不關心 臟數據,允許臨時臟數據可忽略);
總結:
- 我們能放入緩存的數據本就不應該是實時性、一致性要求超高的。所以緩存數據的時候加上過期時間,保 證每天拿到當前最新數據即可。
- 我們不應該過度設計,增加系統的復雜性 。
- 遇到實時性、一致性要求高的數據,就應該查數據庫,即使慢點。