Redis和MySQL如何保持資料一致性?

danny_2018發表於2022-02-17

在高併發的場景下,大量的請求直接訪問Mysql很容易造成效能問題。所以,我們都會用Redis來做資料的快取,削減對資料庫的請求。但是,Mysql和Redis是兩種不同的資料庫,如何保證不同資料庫之間資料的一致性就非常關鍵了。

1.導致資料不一致的原因

在高併發的業務場景下,資料庫大多數情況都是使用者併發訪問最薄弱的環節。

所以,就需要使用redis做一個緩衝操作,讓請求先訪問到redis,而不是直接訪問MySQL等資料庫。

讀取快取步驟一般沒有什麼問題,但是一旦涉及到資料更新:資料庫和快取更新,就容易出現快取(Redis)和資料庫(MySQL)間的資料一致性問題。

這個業務場景,主要是解決讀資料從Redis快取,一般都是按照下圖的流程來進行業務操作。

2.快取先後刪除問題

不管是先寫MySQL資料庫,再刪除Redis快取;還是先刪除快取,再寫庫,都有可能出現資料不一致的情況。

2.1 先刪除快取

如果先刪除Redis快取資料,然而還沒有來得及寫入MySQL,另一個執行緒就來讀取

這個時候發現快取為空,則去Mysql資料庫中讀取舊資料寫入快取,此時快取中為髒資料。

然後資料庫更新後發現Redis和Mysql出現了資料不一致的問題

2.2 後刪除快取

如果先寫了庫,然後再刪除快取,不幸的寫庫的執行緒掛了,導致了快取沒有刪除

這個時候就會直接讀取舊快取,最終也導致了資料不一致情況

因為寫和讀是併發的,沒法保證順序,就會出現快取和資料庫的資料不一致的問題

3 解決方案

3.1 延時雙刪策略

3.1.1 基本思路

在寫庫前後都進行redis.del(key)操作,並且設定合理的超時時間。

虛擬碼如下:

public void write( String key, Object data ){ redis.delKey( key ); db.updateData( data ); Thread.sleep( 500 ); redis.delKey( key );}br

3.1.2 具體步驟

1.先刪除快取

2.再寫資料庫

3.休眠500毫秒

4.再次刪除快取

問題:這個500毫秒怎麼確定的,具體該休眠多久時間呢?

需要評估自己的專案的讀資料業務邏輯的耗時。

這麼做的目的,就是確保讀請求結束,寫請求可以刪除讀請求造成的快取髒資料。

當然這種策略還要考慮redis和資料庫主從同步的耗時。

最後的的寫資料的休眠時間:則在讀資料業務邏輯的耗時基礎上,加幾百ms即可。比如:休眠1秒。

3.1.3 設定快取過期時間是關鍵點

從理論上來說,給快取設定過期時間,是保證最終一致性的解決方案

所有的寫操作以資料庫為準,只要到達快取過期時間,快取刪除

如果後面還有讀請求的話,就會從資料庫中讀取新值然後回填快取

3.1.4 方案缺點

結合雙刪策略+快取超時設定,這樣最差的情況就是:

在快取過期時間內發生資料存在不一致

同時又增加了寫請求的耗時。

3.2 非同步更新快取(基於Mysql binlog的同步機制)

3.2.1 整體思路

1.涉及到更新的資料操作,利用Mysql binlog 進行增量訂閱消費

2.將訊息傳送到訊息佇列

3.透過訊息佇列消費將增量資料更新到Redis上

4.操作情況

讀取Redis快取:熱資料都在Redis上

寫Mysql:增刪改都是在Mysql進行操作

更新Redis資料:Mysql的資料操作都記錄到binlog,透過訊息佇列及時更新到Redis上

3.2.2 Redis更新過程

(1) 資料操作主要分為兩種:

一種是全量(將所有資料一次性寫入Redis)

一種是增量(實時更新)

這裡說的是增量,指的是mysql的update、insert、delate變更資料。

(2)讀取binlog後分析 ,利用訊息佇列,推送更新各臺的redis快取資料。

這樣一旦MySQL中產生了新的寫入、更新、刪除等操作,就可以把binlog相關的訊息推送至Redis

Redis再根據binlog中的記錄,對Redis進行更新

其實這種機制,很類似MySQL的主從備份機制,因為MySQL的主備也是透過binlog來實現的資料一致性

這裡的訊息推送工具你也可以採用別的第三方:kafka、rabbitMQ等來實現推送更新Redis!

總結

在高併發應用場景下,如果是對資料一致性要求高的情況下,要定位好導致資料和快取不一致的原因。

解決高併發場景下資料一致性的方案有兩種,分別是延時雙刪策略和非同步更新快取兩種方案。

另外,設定快取的過期時間是保證資料保持一致性的關鍵操作,需要結合業務進行合理的設定。

來自 “ 架構之美 ”, 原文作者:架構之美;原文連結:https://mp.weixin.qq.com/s/bscB11IfOGuS0DARB8ldBQ,如有侵權,請聯絡管理員刪除。

相關文章