實現緩存最終一致性的兩種方案
阿新 • • 發佈:2019-01-23
日誌 技術分享 頻率 數據庫更新 redis緩存 bsp 不用 客戶端 cdn
一、重客戶端
寫入緩存:
應用同時更新數據庫和緩存
如果數據庫更新成功,則開始更新緩存,否則如果數據庫更新失敗,則整個更新過程失敗。
判斷更新緩存是否成功,如果成功則返回
如果緩存沒有更新成功,則將數據發到MQ中
應用監控MQ通道,收到消息後繼續更新Redis。
問題點:如果更新Redis失敗,同時在將數據發到MQ之前的時間,應用重啟了,這時候MQ就沒有需要更新的數據,如果Redis對所有數據沒有設置過期時間,同時在讀多寫少的場景下,只能通過人工介入來更新緩存。
讀緩存:
如何來解決這個問題?那麽在寫入Redis數據的時候,在數據中增加一個時間戳插入到Redis中。在從Redis中讀取數據的時候,首先要判斷一下當前時間有沒有過期,如果沒有則從緩存中讀取,如果過期了則從數據庫中讀取最新數據覆蓋當前Redis數據並更新時間戳。具體過程如下圖所示:
二、客戶端數據庫與緩存解耦
上述方案對於應用的研發人員來講比較重,需要研發人員同時考慮數據庫和Redis是否成功來做不同方案,如何讓研發人員只關註數據庫層面,而不用關心緩存層呢?請看下圖:
應用直接寫數據到數據庫中。
數據庫更新binlog日誌。
利用Canal中間件讀取binlog日誌。
Canal借助於限流組件按頻率將數據發到MQ中。
應用監控MQ通道,將MQ的數據更新到Redis緩存中。
可以看到這種方案對研發人員來說比較輕量,不用關心緩存層面,而且這個方案雖然比較重,但是卻容易形成統一的解決方案。
?
實現緩存最終一致性的兩種方案