tft每日頭條

 > 科技

 > 如何保證redis與數據庫一緻

如何保證redis與數據庫一緻

科技 更新时间:2025-02-05 04:59:07
背景

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

數據不一緻的原因

導緻數據不一緻的原因

1、在高并發的業務場景下,數據庫大多數情況都是用戶并發訪問最薄弱的環節。

2、所以,就需要使用redis做一個緩沖操作,讓請求先訪問到redis,而不是直接訪問MySQL等數據庫。

3、讀取緩存步驟一般沒有什麼問題,但是一旦涉及到數據更新:數據庫和緩存更新,就容易出現緩存(Redis)和數據庫(MySQL)間的數據一緻性問題。

4、這個業務場景,主要是解決讀數據從Redis緩存,一般都是按照下圖的流程來進行業務操作

如何保證redis與數據庫一緻(Redis和MySQL如何保持數據一緻性)1

緩存先後删除問題

不管是先寫MySQL數據庫,再删除Redis緩存;還是先删除緩存,再寫庫,都有可能出現數據不一緻的情況。

先删除緩存

pan class="nolink">1、如果先删除Redis緩存數據,然而還沒有來得及寫入MySQL,另一個線程就來讀取

pan class="nolink">2、這個時候發現緩存為空,則去Mysql數據庫中讀取舊數據寫入緩存,此時緩存中為髒數據。

pan class="nolink">3、然後數據庫更新後發現Redis和Mysql出現了數據不一緻的問題

後删除緩存

1、如果先寫了庫,然後再删除緩存,不幸的寫庫的線程挂了,導緻了緩存沒有删除

2、這個時候就會直接讀取舊緩存,最終也導緻了數據不一緻情況

3、因為寫和讀是并發的,沒法保證順序,就會出現緩存和數據庫的數據不一緻的問題

解決方案延時雙删策略基本思路

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

僞代碼如下:

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

具體步驟

1、先删除緩存2、再寫數據庫3、休眠500毫秒4、再次删除緩存

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

pan class="nolink">1、需要評估自己的項目的讀數據業務邏輯的耗時。

pan class="nolink">2、這麼做的目的,就是确保讀請求結束,寫請求可以删除讀請求造成的緩存髒數據。

pan class="nolink">3、當然這種策略還要考慮redis和數據庫主從同步的耗時。

pan class="nolink">4、最後的的寫數據的休眠時間:則在讀數據業務邏輯的耗時基礎上,加幾百ms即可。

比如:休眠1秒。

設置緩存過期時間是關鍵點

1、從理論上來說,給緩存設置過期時間,是保證最終一緻性的解決方案

2、所有的寫操作以數據庫為準,隻要到達緩存過期時間,緩存删除

3、如果後面還有讀請求的話,就會從數據庫中讀取新值然後回填緩存

方案缺點

結合雙删策略 緩存超時設置,這樣最差的情況就是:

1、在緩存過期時間内發生數據存在不一緻

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

異步更新緩存(基于Mysql binlog的同步機制)整體思路

1、涉及到更新的數據操作,利用Mysql binlog 進行增量訂閱消費

2、将消息發送到消息隊列

3、通過消息隊列消費将增量數據更新到Redis上

4、.操作情況

讀取Redis緩存:熱數據都在Redis上寫Mysql:增删改都是在Mysql進行操作更新Redis數據:Mysql的數據操作都記錄到binlog,通過消息隊列及時更新到Redis上

Redis更新過程

數據操作主要分為兩種:

1、一種是全量(将所有數據一次性寫入Redis)

2、一種是增量(實時更新)

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

讀取binlog後分析 ,利用消息隊列,推送更新各台的redis緩存數據。

pan class="nolink">1、這樣一旦MySQL中産生了新的寫入、更新、删除等操作,就可以把binlog相關的消息推送至Redis

pan class="nolink">2、Redis再根據binlog中的記錄,對Redis進行更新

pan class="nolink">3、其實這種機制,很類似MySQL的主從備份機制,因為MySQL的主備也是通過binlog來實現的數據一緻性

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

總結

在高并發應用場景下,如果是對數據一緻性要求高的情況下,要定位好導緻數據和緩存不一緻的原因。

解決高并發場景下數據一緻性的方案有兩種,分别是延時雙删策略和異步更新緩存兩種方案。

另外,設置緩存的過期時間是保證數據保持一緻性的關鍵操作,需要結合業務進行合理的設置。

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关科技资讯推荐

热门科技资讯推荐

网友关注

Copyright 2023-2025 - www.tftnews.com All Rights Reserved