1. 程式人生 > >實現緩存最終一致性的兩種方案

實現緩存最終一致性的兩種方案

日誌 技術分享 頻率 數據庫更新 redis緩存 bsp 不用 客戶端 cdn

  一、重客戶端

  寫入緩存:

  

技術分享圖片

  應用同時更新數據庫和緩存

  如果數據庫更新成功,則開始更新緩存,否則如果數據庫更新失敗,則整個更新過程失敗。

  判斷更新緩存是否成功,如果成功則返回

  如果緩存沒有更新成功,則將數據發到MQ中

  應用監控MQ通道,收到消息後繼續更新Redis。

  問題點:如果更新Redis失敗,同時在將數據發到MQ之前的時間,應用重啟了,這時候MQ就沒有需要更新的數據,如果Redis對所有數據沒有設置過期時間,同時在讀多寫少的場景下,只能通過人工介入來更新緩存。

  讀緩存:

  如何來解決這個問題?那麽在寫入Redis數據的時候,在數據中增加一個時間戳插入到Redis中。在從Redis中讀取數據的時候,首先要判斷一下當前時間有沒有過期,如果沒有則從緩存中讀取,如果過期了則從數據庫中讀取最新數據覆蓋當前Redis數據並更新時間戳。具體過程如下圖所示:

  

技術分享圖片

  二、客戶端數據庫與緩存解耦

  上述方案對於應用的研發人員來講比較重,需要研發人員同時考慮數據庫和Redis是否成功來做不同方案,如何讓研發人員只關註數據庫層面,而不用關心緩存層呢?請看下圖:

  

技術分享圖片

  應用直接寫數據到數據庫中。

  數據庫更新binlog日誌。

  利用Canal中間件讀取binlog日誌。

  Canal借助於限流組件按頻率將數據發到MQ中。

  應用監控MQ通道,將MQ的數據更新到Redis緩存中。

  可以看到這種方案對研發人員來說比較輕量,不用關心緩存層面,而且這個方案雖然比較重,但是卻容易形成統一的解決方案。

?

實現緩存最終一致性的兩種方案