欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何解決緩存數(shù)據(jù)不一致性問題

 更新時間:2025年01月10日 09:29:28   作者:Wchisper  
文章主要討論了緩存和數(shù)據(jù)庫數(shù)據(jù)一致性的問題,包括數(shù)據(jù)不一致的原因、查詢和更新數(shù)據(jù)的邏輯、緩存雙刪方案以及優(yōu)化建議

1. 數(shù)據(jù)不一致的原因

1.1 雙寫導(dǎo)致數(shù)據(jù)不一致

由于分布性系統(tǒng),不能保證每個節(jié)點都可用,所有可能引起 Redis 在極限情況下數(shù)據(jù)沒有寫入成功,那么此時緩存中的數(shù)據(jù)和數(shù)據(jù)庫數(shù)據(jù)不一致。

數(shù)據(jù)的更新為什么會成功:因為事務(wù)保證數(shù)據(jù)不管是成功還是失敗,都不會有臟數(shù)據(jù)。

1.2 高并發(fā)導(dǎo)致數(shù)據(jù)不一致

數(shù)據(jù)在修改的過程中必定會存在網(wǎng)絡(luò)延時,因為分布式系統(tǒng)節(jié)點相互獨立部署,那么在并發(fā)讀的情況之下,還沒來得及修改完,那么對于讀操作,讀到的數(shù)據(jù)都是老的數(shù)據(jù)

如果是某些不嚴(yán)謹(jǐn)?shù)那闆r,無所謂,如果是極致的嚴(yán)謹(jǐn),那么就不能這么做了。比如我們的環(huán)境監(jiān)測,大氣的一些數(shù)據(jù)會每隔1-2分鐘更新,甚至有的是5分鐘更新,所以如果讀到的是一些老的數(shù)據(jù),是沒有關(guān)系的,因為最終幾秒或者幾十秒以后會更新,這些數(shù)據(jù)的來去不會很大,而且我們能容忍一定的誤差,所以也就無所謂了。

2. 查詢數(shù)據(jù)的邏輯

先請求先到 Redis,如果命中則返回結(jié)果。如果 Redis 中沒有數(shù)據(jù),則從數(shù)據(jù)庫查詢,再寫入到緩存中,再返回結(jié)果。

3. 更新數(shù)據(jù)的邏輯

3.1 先刪除緩存,再更新數(shù)據(jù)庫

3.1.1 方案一

在并發(fā)不高的情況下:先刪除 Redis 中的舊數(shù)據(jù)。更新數(shù)據(jù)庫中的數(shù)據(jù)。再將數(shù)據(jù)庫中的數(shù)據(jù)同步到 Redis 中。

3.1.2 方案二

在高并發(fā)的情況下,假設(shè)有請求 A 進行更新操作,另一個請求 B 進行查詢操作,那么有可能會出現(xiàn):

  1. A 進行更新操作前,先刪除了緩存
  2. B 查詢發(fā)現(xiàn)緩存不存在
  3. B 查詢數(shù)據(jù)庫的舊值
  4. B 將舊值寫入到緩存
  5. A 執(zhí)行更新,將新值寫入到數(shù)據(jù)庫
  6. 后續(xù)的請求因為發(fā)現(xiàn)緩存中有數(shù)據(jù),導(dǎo)致 A 更新的數(shù)據(jù)一直無法更新到緩存中,這樣便出現(xiàn)了數(shù)據(jù)庫與緩存不一致的情況。

3.2 先更新數(shù)據(jù)庫,再刪除緩存

3.2.1 方案一

該方案雖然存在并發(fā)問題,但是出現(xiàn)上述情況的概率是極低的,也有一些企業(yè)在使用這種方案。

在超高并發(fā)下,請求 A 執(zhí)行更新操作,請求 B 進行查詢操作:

  1. B 將新值寫入到數(shù)據(jù)庫
  2. A 查詢 Redis 得到舊數(shù)據(jù)
  3. 線程 B 刪除緩存
  4. 這樣就會導(dǎo)致 A 修改數(shù)據(jù) —> A 刪除 Redis 之間出現(xiàn)臟數(shù)據(jù)。

3.2.2 方案二

在超高并發(fā)下,請求 A 執(zhí)行更新操作,請求 B 進行查詢操作:

  1. 緩存剛好失效
  2. B 查詢數(shù)據(jù)庫,得到一個舊值
  3. A 將新值寫入到數(shù)據(jù)庫
  4. 線程 A 刪除緩存
  5. B 將舊值寫入到緩存
  6. 這樣就會導(dǎo)致后續(xù)的請求之間出現(xiàn)臟數(shù)據(jù)。

3.3 緩存雙刪方案

它的流程為:

  1. 先刪除緩存
  2. 再寫數(shù)據(jù)庫
  3. 休眠一段時間,再刪除緩存

回顧一下方案“先刪除緩存,再更新數(shù)據(jù)庫”可能造成數(shù)據(jù)庫與緩存不一致的情況。

假設(shè)有請求 A 進行更新操作,另一個請求 B 進行查詢操作,如果使用緩存雙刪策略:

  1. A 進行更新操作前,先刪除了緩存
  2. B 查詢發(fā)現(xiàn)緩存不存在
  3. B 查詢數(shù)據(jù)庫的舊值
  4. B 將舊值寫入到緩存
  5. A 執(zhí)行更新,將新值寫入到數(shù)據(jù)庫,執(zhí)行休眠 Thread.sleep(t)
  6. A 蘇醒,再次將緩存中的值刪除

緩存雙刪的優(yōu)點是大大降低了數(shù)據(jù)庫與緩存不一致的概率的發(fā)生,注意這里只是降低,并不是說完全的避免,途中紅框的地方就是緩存臟數(shù)據(jù)的時間,缺點為一定程度上降低了吞吐量,因為系統(tǒng)進行了休眠

這里為什么要采用休眠,對數(shù)據(jù)進行延遲緩存,原因是

  1. 例如:如果在 A 刪除緩存之后,數(shù)據(jù)庫修改之間 C 再次請求數(shù)據(jù)庫,將老的信息存儲進緩存,那么后續(xù)所有的請求打在緩存中,還是獲取到老的數(shù)據(jù)
  2. 在分庫分表的情況下,延遲一定的時間,也保證了,修改后的數(shù)據(jù)全部同步到所有的數(shù)據(jù)庫中。

4. 擴展:其它的解決雙寫一直問題

通過監(jiān)聽數(shù)據(jù)庫日志,來修改 Redis 的數(shù)據(jù),使數(shù)據(jù)的修改達到準(zhǔn)實時的級別,例如:canal。但是這種情況下會有一些時間的延遲,也會短暫的產(chǎn)生臟數(shù)據(jù)。這種情況適用于寫多讀少的場景

完全使用緩存作為數(shù)據(jù)庫,后面在定時任務(wù)修改數(shù)據(jù)庫數(shù)據(jù)。這種情況下,沒要求對 Redis 的三高要求非常高,可以采用云廠商的 Redis 服務(wù)。

讀取的時候只提供 Redis,也就是說,當(dāng)更新操作一開始從 Redis 中刪除數(shù)據(jù)了,用戶去讀 Redis,如果沒有是不會從數(shù)據(jù)庫中讀的,因為只提供 Redis 的讀取,寫入的時候只在數(shù)據(jù)新增以及更新后才會放入到 Redis,那么如此一來,并發(fā)讀的時候就不會從數(shù)據(jù)庫讀取老的數(shù)據(jù)并且放入 Redis 中了。沒有讀到也沒關(guān)系,做一些空數(shù)據(jù)的處理,可能會有個幾百毫秒或者 1-2s 的延遲,但是可以忍受。但是要注意做好緩存穿透的校驗處理。

5. 緩存數(shù)據(jù)的思考

我們能放入緩存的數(shù)據(jù)本就不應(yīng)該是實時性、一致性要求超高的,所以緩存數(shù)據(jù)的時候加上過期時間,保證每天拿到當(dāng)前最新數(shù)據(jù)即可。

我們不應(yīng)該過度設(shè)計,增加系統(tǒng)的復(fù)雜性,遇到實時性、一致性要求高的數(shù)據(jù),就應(yīng)該查數(shù)據(jù)庫,即使慢點。

超高并發(fā)場景的一致性,都是最終一致性,也就是弱一致性,所以要考慮每一個環(huán)節(jié)可能失敗的情況,補償 job 也是常有的。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 淺談Redis如何應(yīng)對并發(fā)訪問

    淺談Redis如何應(yīng)對并發(fā)訪問

    本文主要介紹了Redis如何應(yīng)對并發(fā)訪問,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Redis主從集群切換數(shù)據(jù)丟失的解決方案

    Redis主從集群切換數(shù)據(jù)丟失的解決方案

    這篇文章主要介紹了Redis主從集群切換數(shù)據(jù)丟失的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Redis Template實現(xiàn)分布式鎖的實例代碼

    Redis Template實現(xiàn)分布式鎖的實例代碼

    使用Redis的SETNX命令獲取分布式鎖的步驟,接下來通過本文給大家介紹Redis Template實現(xiàn)分布式鎖的實例代碼,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2018-09-09
  • Redis分布式鎖解決超賣問題

    Redis分布式鎖解決超賣問題

    超賣問題是典型的多線程安全問題,本文就來介紹一下Redis分布式鎖解決超賣問題,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • Redis實現(xiàn)集群搭建+集群讀寫的示例

    Redis實現(xiàn)集群搭建+集群讀寫的示例

    本文介紹了Redis集群的搭建和讀寫操作,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-02-02
  • Window下Redis的安裝和部署詳細(xì)圖文教程

    Window下Redis的安裝和部署詳細(xì)圖文教程

    Windows?版本的?Redis?是?Microsoft?的開源部門提供的?Redis.?這個版本的?Redis?適合開發(fā)人員學(xué)習(xí)使用,生產(chǎn)環(huán)境中使用?Linux?系統(tǒng)上的?Redis,?這里講解了這兩種的安裝和下載,按照你們需要的liunx?或window步驟來?就可以了
    2024-05-05
  • Redis的緩存更新策略及最佳實踐方案

    Redis的緩存更新策略及最佳實踐方案

    這篇文章主要介紹了Redis的緩存更新策略及最佳實踐方案,當(dāng)我們向redis插入太多數(shù)據(jù),此時就可能會導(dǎo)致緩存中的數(shù)據(jù)過多,所以redis會對部分?jǐn)?shù)據(jù)進行更新,或者把它成為淘汰更合適,需要的朋友可以參考下
    2023-08-08
  • SpringBoot讀寫Redis客戶端并實現(xiàn)Jedis技術(shù)切換功能

    SpringBoot讀寫Redis客戶端并實現(xiàn)Jedis技術(shù)切換功能

    這篇文章主要介紹了SpringBoot讀寫Redis客戶端并實現(xiàn)技術(shù)切換功能,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-01-01
  • Redis并發(fā)問題解決方案

    Redis并發(fā)問題解決方案

    在當(dāng)前的互聯(lián)網(wǎng)環(huán)境中,高并發(fā)業(yè)務(wù)場景十分常見,本文就來介紹一下Redis并發(fā)問題解決方案,具有一定的參考價值,感興趣的可以了解一下
    2023-11-11
  • Redis全量同步和增量同步原理

    Redis全量同步和增量同步原理

    主從第一次同步是全量同步:也就是說,當(dāng)你主從節(jié)點連接建立后,需要執(zhí)行一次全量同步,但如果slave重啟后同步,此時slave重啟后,slave節(jié)點和master節(jié)點的數(shù)據(jù)之間有落后,因此需要進行增量同步,感興趣的同學(xué)可以參考閱讀
    2023-04-04

最新評論