背景
緩存是數據庫的副本,應用在查詢數據時,先從緩存中查詢,如果命中直接返回,如果未命中,去數據庫查詢最新數據並返回,同時寫入緩存。
緩存能夠有效地加速應用的讀寫速度,同時也可以降低后端負載。是應用架構中常用的一種技術。
問題
當業務發生時,系統狀態改變,需要同時修改數據庫和緩存的數據。如何保證應用從緩存讀取到最新的數據,且即使數據庫立即崩潰,數據也不丟失?這就是緩存與數據庫的一致性問題。
分析
一個系統狀態同時存在於緩存和數據庫,緩存是數據庫的副本,數據庫可以讀和寫,把緩存的寫看作是讀緩存未命中的一部分,則緩存只有讀。只要保證數據庫的寫對緩存的可見性,就能保證它們的一致性。
解決方案
讀緩存
- 如果命中直接返回。
- 如果未命中
- 獲取key對應的分布式鎖
- 讀數據庫
- 返回結果並更新緩存
- 釋放key對應的分布式鎖
寫數據庫
- 獲取緩存key對應的分布式鎖
- 操作緩存刪除鍵
- 修改數據庫
- 釋放緩存key對應的分布式鎖
總結
在系統狀態不變時,緩存與數據庫是一致的。在系統狀態變化時,通過分布式鎖串行化對狀態的讀寫。寫時先讓緩存(即數據庫副本)失效,只需保證數據庫本身的更新;寫后的讀操作恢復緩存。即狀態變化過程中,只有數據庫保存狀態,沒有副本,數據是一致的。