最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis延遲雙刪的具體使用

 更新時間:2025年08月21日 10:01:25   作者:陳寶子  
本文主要討論了延時雙刪策略,用于解決緩存與數(shù)據(jù)庫數(shù)據(jù)不一致的問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

1、何為延時雙刪

延遲雙刪(Delay Double Delete)是一種在數(shù)據(jù)更新或刪除時為了保證數(shù)據(jù)一致性而采取的策略。這種策略通常用于解決數(shù)據(jù)在緩存和數(shù)據(jù)庫中不一致的問題。

具體來說,在某些場景下,我們需要先更新或刪除數(shù)據(jù)庫中的數(shù)據(jù),然后再更新或刪除緩存中的數(shù)據(jù),以保證數(shù)據(jù)的一致性。但在某些情況下,由于網(wǎng)絡延遲、服務器故障或其他原因,可能導致緩存中的數(shù)據(jù)更新或刪除失敗,從而導致數(shù)據(jù)庫和緩存中的數(shù)據(jù)不一致

值得注意的是,不管哪種方案,都避免不了Redis存在臟數(shù)據(jù)的問題,只能減輕這個問題,要想徹底解決,得要用到同步鎖和對應的業(yè)務邏輯層面解決。

2、常用緩存策略

2.1、介紹

這里只提及Cache Aside(旁路緩存)策略,這是我們操作Redis時最常用的一個策略,在該策略中應用程序直接與「數(shù)據(jù)庫、緩存」交互,并負責對緩存的維護,該策略又可以細分為「讀策略」和「寫策略」。

寫策略:先更新數(shù)據(jù)庫中的數(shù)據(jù),再刪除緩存中的數(shù)據(jù)。

讀策略

  • 如果讀取的數(shù)據(jù)命中了緩存,則直接返回數(shù)據(jù);
  • 如果讀取的數(shù)據(jù)沒有命中緩存,則從數(shù)據(jù)庫中讀取數(shù)據(jù),然后將數(shù)據(jù)寫入到緩存,并且返回給用戶。

注意,寫策略的步驟的順序不能倒過來,即不能先刪除緩存再更新數(shù)據(jù)庫,原因是在「讀+寫」并發(fā)的時候,會出現(xiàn)緩存和數(shù)據(jù)庫的數(shù)據(jù)不一致性的問題。

2.2、先刪緩存后更庫

前面提及到寫策略的步驟的順序不能倒過來,即不能先刪除緩存再更新數(shù)據(jù)庫,這里舉一個例子演示:

  • 假設某個用戶的年齡是20,請求A更新用戶年齡為21,所以它會刪除緩存中的內(nèi)容。
  • 這時,另一個請求B讀取這個用戶的年齡,它查詢緩存發(fā)現(xiàn)未命中后,會從數(shù)據(jù)庫中讀取到年齡為20,并且寫回到緩存中。
  • 請求A繼續(xù)更改數(shù)據(jù)庫,將用戶的年齡更新為21。
  • 最終,該用戶年齡在緩存中是20(舊值),在數(shù)據(jù)庫中是21(新值),緩存和數(shù)據(jù)庫的數(shù)據(jù)不一致。

2.3、先更庫后刪緩存

那么**「先更新數(shù)據(jù)庫再刪除緩存」一定不會有數(shù)據(jù)不一致的問題嗎**?繼續(xù)用「讀 + 寫」請求的并發(fā)的場景來分析:

  • 假如某個用戶數(shù)據(jù)在緩存中不存在,請求A讀取數(shù)據(jù)時從數(shù)據(jù)庫中查詢到年齡為 20。
  • 在未寫入緩存中時另一個請求B更新數(shù)據(jù)。請求B更新數(shù)據(jù)庫中的年齡為 21,并且清空緩存。
  • 這時請求A把從數(shù)據(jù)庫中讀到的年齡為20的數(shù)據(jù)寫入到緩存中。
  • 最終,該用戶年齡在緩存中是 20(舊值),在數(shù)據(jù)庫中是 21(新值),緩存和數(shù)據(jù)庫數(shù)據(jù)不一致。

從上面的理論上分析,先更新數(shù)據(jù)庫,再刪除緩存也是會出現(xiàn)數(shù)據(jù)不一致性的問題,但是在實際中,這個問題出現(xiàn)的概率并不高。這主要有以下原因:

  • 緩存的寫入通常要遠遠快于數(shù)據(jù)庫的寫入。
  • 所以在實際中很難出現(xiàn)請求B已經(jīng)更新了數(shù)據(jù)庫并且刪除了緩存請求A更新完緩存的情況。
  • 而一旦請求A早于請求B刪除緩存之前更新了緩存,那么接下來的請求就會因為緩存不命中而從數(shù)據(jù)庫中重新讀取數(shù)據(jù),所以一般不會出現(xiàn)這種不一致的情況。

2.4、使用場景

Cache Aside 策略適合讀多寫少的場景,不適合寫多的場景,因為當寫入比較頻繁時,緩存中的數(shù)據(jù)會被頻繁地清理,這樣會對緩存的命中率有一些影響。如果業(yè)務對緩存命中率有嚴格的要求,那么可以考慮兩種解決方案:

  • 一種做法是在更新數(shù)據(jù)時也更新緩存,只是在更新緩存前先加一個分布式鎖。因為這樣在同一時間只允許一個線程更新緩存,就不會產(chǎn)生并發(fā)問題了。當然這么做對于寫入的性能會有一些影響;
  • 另一種做法同樣也是在更新數(shù)據(jù)時更新緩存,只是給緩存加一個較短的過期時間。這樣即使出現(xiàn)緩存不一致的情況,緩存的數(shù)據(jù)也會很快過期,對業(yè)務的影響也是可以接受。

3、延時雙刪實現(xiàn)

在前面介紹到,先更新數(shù)據(jù)庫后刪Redis緩存是一致性相對最高的。這是就有人舉手了:我就想要先刪緩存怎么辦?這時延時雙刪就出現(xiàn)了,針對「先刪除緩存,再更新數(shù)據(jù)庫」方案在「讀 + 寫」并發(fā)請求而造成緩存不一致的解決辦法是「延遲雙刪」。

延遲雙刪實現(xiàn)的偽代碼如下:

#刪除緩存
redis.delKey(X)
#更新數(shù)據(jù)庫
db.update(X)
#睡眠
Thread.sleep(N)
#再刪除緩存
redis.delKey(X)

這里做一個詳細介紹:

  1. 首先,代碼先刪除了 Redis 中的緩存數(shù)據(jù),以確保接下來的讀取操作會從數(shù)據(jù)庫中讀取最新的數(shù)據(jù)。
  2. 接著,代碼更新了數(shù)據(jù)庫中的數(shù)據(jù),將數(shù)據(jù)更新為最新的值。
  3. 在此之后,代碼讓當前線程休眠一段時間N,這個時間段是為了給數(shù)據(jù)庫操作足夠的時間來完成,確保數(shù)據(jù)已經(jīng)持久化到數(shù)據(jù)庫中。
  4. 最后,代碼再次刪除 Redis 中的緩存數(shù)據(jù)。這里是延遲雙刪的關鍵步驟。由于之前已經(jīng)刪除了緩存數(shù)據(jù),再次刪除的目的是為了防止在 Thread.sleep(N) 的時間內(nèi)有其他線程讀取到舊的緩存數(shù)據(jù)。因為在這段時間內(nèi),緩存數(shù)據(jù)已經(jīng)被清空,所以其他線程在讀取數(shù)據(jù)時會發(fā)現(xiàn)緩存中不存在,然后從數(shù)據(jù)庫中讀取最新的數(shù)據(jù)并寫入緩存,從而保證了數(shù)據(jù)的一致性。

需要注意的是,這種延遲雙刪策略并不能完全保證數(shù)據(jù)的一致性。

如果在 Thread.sleep(N) 的時間內(nèi)發(fā)生了其他線程的寫入操作,并且將新數(shù)據(jù)寫入了緩存中,那么在第二次刪除緩存時,會將這個新數(shù)據(jù)從緩存中刪除,可能導致緩存和數(shù)據(jù)庫中的數(shù)據(jù)不一致。

因此,延遲雙刪策略只能在一定程度上提高數(shù)據(jù)一致性的概率,但不能完全解決數(shù)據(jù)一致性的問題。更加嚴格的數(shù)據(jù)一致性保證需要使用更復雜的機制,比如使用消息隊列等。

4、為什么要使用延時雙刪

在延時雙刪策略中,當需要更新數(shù)據(jù)庫中的數(shù)據(jù)時,首先會先刪除緩存,然后再進行數(shù)據(jù)庫的更新操作。這樣做的目的是為了避免在數(shù)據(jù)庫更新的過程中,有其他請求讀取了已經(jīng)失效的緩存數(shù)據(jù)。

通過延時雙刪策略,可以保證在數(shù)據(jù)庫更新期間,其他讀取請求在緩存不命中的情況下,會直接讀取數(shù)據(jù)庫的最新數(shù)據(jù),而不會讀取到已經(jīng)失效的緩存數(shù)據(jù)。這樣就保證了數(shù)據(jù)的一致性和緩存的即時更新。

延時雙刪策略雖然會增加一次緩存刪除的開銷,但是可以有效地提高數(shù)據(jù)的一致性,并且在高并發(fā)讀取的場景下,減輕數(shù)據(jù)庫的讀取壓力,提高讀取性能和響應速度。

5、方案選擇

對于先刪除緩存后更新數(shù)據(jù)庫這種方案,由于出現(xiàn)數(shù)據(jù)不一致性的可能性偏高,數(shù)據(jù)庫讀寫壓力偏大以及性能偏低,因此這一方案一般不予與考慮,這里主要對延時雙刪方案先更新數(shù)據(jù)庫后刪除緩存方案進行分析。

針對于前面的介紹,可以分析出以下結(jié)論:

  • 延時雙刪適用于對數(shù)據(jù)一致性要求較高的場景。它能夠保證在數(shù)據(jù)庫更新期間,讀取請求不會讀取到已經(jīng)失效的緩存數(shù)據(jù),從而保證數(shù)據(jù)的一致性。但是它需要進行兩次緩存刪除操作,可能會增加一定的資源開銷;
  • 先更新數(shù)據(jù)庫后刪除緩存適用于對一致性要求較低,對性能要求較高的場景。它能夠減少一次緩存刪除的開銷,但是在數(shù)據(jù)庫更新期間,讀取請求可能會讀取到已經(jīng)失效的緩存數(shù)據(jù),從而導致數(shù)據(jù)不一致。

同時,還可以根據(jù)實際情況做一些權(quán)衡和優(yōu)化。比如可以使用讀寫鎖來減少數(shù)據(jù)庫更新期間的并發(fā)讀取請求,從而降低數(shù)據(jù)不一致的可能性?;蛘呖梢钥紤]使用更高效的緩存淘汰算法,來降低緩存的過期時間,減少緩存失效的影響。

方案優(yōu)點缺點實現(xiàn)復雜度適用場景
先更新數(shù)據(jù)庫后刪除緩存減少了一次緩存刪除的開銷在數(shù)據(jù)庫更新期間,讀取請求可能讀取到失效的緩存數(shù)據(jù)簡單數(shù)據(jù)一致性要求較低、對性能要求較高的場景
延時雙刪保證了數(shù)據(jù)一致性,讀取請求不會讀取到失效的緩存數(shù)據(jù)需要進行兩次緩存刪除操作,增加了一定的資源開銷復雜數(shù)據(jù)一致性要求較高的場景,同時對性能影響有一定容忍度的場景

6、延時雙刪真的完美嗎

在認識到這個方案的時候,我就冒出了這么一種疑問不知道大家有沒有:

為什么要執(zhí)行第一次刪除緩存的操作呢?留著緩存不是也能緩解數(shù)據(jù)庫并發(fā)讀取的壓力嗎?執(zhí)行第一次刪除緩存的操作還會多花費一定的資源去執(zhí)行刪除操作。

為了解決這一個問題我也去查詢了許多資料和博文吸取經(jīng)驗,這個問題也是得到了一定的解決,如果有錯誤希望大伙熱情提出。

首先,**為什么要執(zhí)行第一次刪除緩存的操作?**這是因為在并發(fā)環(huán)境下,如果直接更新數(shù)據(jù)庫而不刪除緩存,會導致臟數(shù)據(jù)問題。考慮以下場景:

  1. 線程A讀取緩存中的舊數(shù)據(jù)。
  2. 線程B更新數(shù)據(jù)庫中的數(shù)據(jù),并刪除緩存。
  3. 線程A繼續(xù)使用緩存中的舊數(shù)據(jù),因為此時它不知道緩存已經(jīng)被刪除。

為了避免這種臟數(shù)據(jù)問題,需要在更新數(shù)據(jù)庫之前,先刪除緩存,這樣其他讀取請求會從數(shù)據(jù)庫中讀取最新數(shù)據(jù)。

接著說為什么需要延遲再次刪除緩存。延遲再次刪除緩存的目的是為了在數(shù)據(jù)庫更新期間,保留舊數(shù)據(jù)的緩存,以緩解數(shù)據(jù)庫并發(fā)讀取的壓力。在延遲時間內(nèi),其他讀取請求會從緩存中讀取舊數(shù)據(jù),而不會直接讀取數(shù)據(jù)庫。

雖然執(zhí)行第一次刪除緩存的操作會帶來一定的資源開銷,但通過合理設置延遲時間和優(yōu)化緩存策略,可以在高并發(fā)讀取場景下,有效降低對數(shù)據(jù)庫的直接讀取次數(shù),從而提高讀取性能和并發(fā)性能。這樣在一段時間內(nèi),仍能從緩存中獲取數(shù)據(jù),減少數(shù)據(jù)庫壓力,而在數(shù)據(jù)庫更新完成后,再次刪除緩存以確保最終的數(shù)據(jù)一致性。

這么看來是有那么一點點脫褲子放屁的感覺哈,我剛開始也是有這么一種感覺的,但是一切都要以實際場景來決定的。

第一次刪除緩存的操作是為了以一定的資源開銷為代價,讓緩存中的舊數(shù)據(jù)在一定時間內(nèi)相對較新,以便在數(shù)據(jù)庫更新期間,其他讀取請求可以從緩存中獲取舊數(shù)據(jù),從而減輕對數(shù)據(jù)庫的直接讀取壓力。這有些類似于寫鎖,在更新數(shù)據(jù)庫時,盡可能的保證寫之前的數(shù)據(jù)是最新的,但只是盡可能,雖然大部分保證了,但是還是會有一定的可能會出現(xiàn)臟數(shù)據(jù)問題。

這樣做的目的是為了在高并發(fā)讀取場景下提高性能,通過緩存中的舊數(shù)據(jù),避免大量讀取請求直接訪問數(shù)據(jù)庫,降低數(shù)據(jù)庫的并發(fā)讀取壓力。同時,因為緩存的更新是延遲進行的,所以在一定時間內(nèi),讀取請求會持續(xù)從緩存中獲取數(shù)據(jù),而不會頻繁訪問數(shù)據(jù)庫,從而提高了讀取性能和響應速度。

在第一次刪除緩存到更新數(shù)據(jù)庫期間,請求壓力其實是由數(shù)據(jù)庫服務和Redis服務兩者一起承擔的。當請求緩存不命中時,請求會打到數(shù)據(jù)庫查詢數(shù)據(jù)并寫回緩存,之后請求壓力將會由Redis服務承擔。

7、如何確定延時的時間

確定延時雙刪中延時的時間是一個需要根據(jù)實際場景和需求來進行權(quán)衡的過程。延時的時間需要根據(jù)數(shù)據(jù)庫的更新操作耗時、緩存的過期時間以及應用的實際負載情況,通過不斷的測試來確定。

如果數(shù)據(jù)庫的更新操作通常很快,可以選擇較短的延時時間,比如幾百毫秒或一秒鐘。這樣可以盡快地更新緩存,減少讀取請求的直接訪問數(shù)據(jù)庫的次數(shù),提高緩存的讀取性能。

如果數(shù)據(jù)庫的更新操作較為耗時,可能需要選擇較長的延時時間,比如幾秒鐘或更長。這樣可以保證數(shù)據(jù)庫的更新操作完成后再刪除緩存,避免讀取請求獲取到過期的緩存數(shù)據(jù),保證數(shù)據(jù)一致性。

另外,延時的時間還需要考慮緩存的過期時間。如果緩存的過期時間較長,可以適當縮短延時的時間;如果緩存的過期時間較短,可以適當延長延時的時間,以免過早地刪除緩存導致數(shù)據(jù)不一致。

對于還需要考慮緩存的過期時間原因如下:

假設在延時雙刪策略中,第一次刪除緩存后,會有一段時間的延時,然后再進行第二次刪除緩存。如果此時緩存的過期時間設置得很短,比如只有幾秒鐘,那么在第二次刪除緩存之前,緩存可能已經(jīng)過期,而應用程序在讀取緩存時會發(fā)現(xiàn)緩存已失效,從而不得不去數(shù)據(jù)庫中查詢最新數(shù)據(jù)。

為了避免這種情況,延時雙刪的延時時長應該要小于緩存的過期時間,確保在第二次刪除緩存之前,緩存還是有效的,這樣可以保證應用程序讀取到的數(shù)據(jù)是一致的。

同時還需要考慮數(shù)據(jù)更新的頻率和緩存的使用情況。如果數(shù)據(jù)更新較為頻繁,那么延時雙刪的延時時長應該要適當縮短,以便及時更新緩存;如果緩存的使用率很低,可以適當延長延時時長,以減少對緩存服務的壓力。

到此這篇關于Redis延遲雙刪的具體使用的文章就介紹到這了,更多相關Redis延遲雙刪內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Redis配置ACL訪問控制列表的實現(xiàn)

    Redis配置ACL訪問控制列表的實現(xiàn)

    配置Redis的ACL(訪問控制列表)涉及創(chuàng)建和管理用戶、設置用戶的權(quán)限,并確保用戶只能執(zhí)行被允許的命令和訪問被允許的鍵,本文將詳細介紹通過配置文件和動態(tài)命令來配置Redis的ACL,感興趣的可以了解一下
    2025-10-10
  • Redis配置文件最佳實踐

    Redis配置文件最佳實踐

    這篇文章主要介紹了Redis配置文件詳解,本文主要是根據(jù)Redis6.0.x版本的配置文件講解,其它版本的也可以當做一個參考,需要的朋友可以參考下
    2025-05-05
  • redis-sentinel基礎概念及部署流程

    redis-sentinel基礎概念及部署流程

    Redis Sentinel是Redis的高可用解決方案,通過監(jiān)控主從節(jié)點、自動故障轉(zhuǎn)移、通知機制及配置提供,實現(xiàn)集群故障恢復與服務持續(xù)可用,核心組件包括Sentinel節(jié)點、主節(jié)點和從節(jié)點,部署需配置參數(shù),驗證主節(jié)點變化即成功
    2025-08-08
  • Redis簡單動態(tài)字符串SDS的實現(xiàn)示例

    Redis簡單動態(tài)字符串SDS的實現(xiàn)示例

    Redis沒有直接復用C語言的字符串,而是新建了SDS,本文主要介紹了Redis簡單動態(tài)字符串SDS的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下
    2023-08-08
  • docker安裝redis的完整步驟詳解

    docker安裝redis的完整步驟詳解

    這篇文章主要介紹了docker安裝redis的完整步驟,包括拉取鏡像、設置配置文件、編寫docker-compose.yml文件啟動Redis以及測試Redis連接,文中通過圖文及代碼介紹的非常詳細,需要的朋友可以參考下
    2025-03-03
  • redis搭建哨兵集群的實現(xiàn)步驟

    redis搭建哨兵集群的實現(xiàn)步驟

    本文主要介紹了redis搭建哨兵集群的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-05-05
  • Redis入門教程詳解

    Redis入門教程詳解

    本文詳細介紹了Redis,文中主要講解了其基本數(shù)據(jù)結(jié)構(gòu)、高級數(shù)據(jù)結(jié)構(gòu)、高級特性、使用場景等,需要了解的朋友可以參考一下
    2021-08-08
  • 解決Redis的緩存與數(shù)據(jù)庫雙寫不一致問題

    解決Redis的緩存與數(shù)據(jù)庫雙寫不一致問題

    在使用緩存和數(shù)據(jù)庫配合時,常見的CacheAsidePattern模式要求讀操作先訪問緩存,若缺失再讀數(shù)據(jù)庫并更新緩存;寫操作則是先寫數(shù)據(jù)庫后刪除緩存,但這種模式可能導致緩存與數(shù)據(jù)庫間的雙寫不一致問題
    2024-10-10
  • Redis總結(jié)筆記(二):C#連接Redis簡單例子

    Redis總結(jié)筆記(二):C#連接Redis簡單例子

    這篇文章主要介紹了Redis總結(jié)筆記(二):C#連接Redis簡單例子,需要的朋友可以參考下
    2015-01-01
  • Redis實現(xiàn)延遲任務的三種方法詳解

    Redis實現(xiàn)延遲任務的三種方法詳解

    延遲任務(Delayed Task)是指在未來的某個時間點,執(zhí)行相應的任務,本文為大家整理了三種常見的實現(xiàn)方法,感興趣的小伙伴可以參考一下
    2025-04-04

最新評論

买车| 昆山市| 延长县| 凤山县| 鄢陵县| 天柱县| 通江县| 岐山县| 东港市| 华阴市| 台山市| 闽侯县| 张家口市| 偏关县| 宁明县| 买车| 黄大仙区| 申扎县| 张家川| 许昌县| 德庆县| 巴青县| 普宁市| 米脂县| 简阳市| 罗田县| 华安县| 余姚市| 稻城县| 晋中市| 大新县| 尖扎县| 蒙城县| 监利县| 和平区| 临泉县| 博湖县| 余江县| 攀枝花市| 靖边县| 罗定市|