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

Redis延遲雙刪的具體使用

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

1、何為延時雙刪

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

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

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

2、常用緩存策略

2.1、介紹

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

寫策略:先更新數(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ù)庫,這里舉一個例子演示:

  • 假設(shè)某個用戶的年齡是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ù)不一致性的問題,但是在實(shí)際中,這個問題出現(xiàn)的概率并不高。這主要有以下原因:

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

2.4、使用場景

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

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

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

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

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

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

這里做一個詳細(xì)介紹:

  1. 首先,代碼先刪除了 Redis 中的緩存數(shù)據(jù),以確保接下來的讀取操作會從數(shù)據(jù)庫中讀取最新的數(shù)據(jù)。
  2. 接著,代碼更新了數(shù)據(jù)庫中的數(shù)據(jù),將數(shù)據(jù)更新為最新的值。
  3. 在此之后,代碼讓當(dāng)前線程休眠一段時間N,這個時間段是為了給數(shù)據(jù)庫操作足夠的時間來完成,確保數(shù)據(jù)已經(jīng)持久化到數(shù)據(jù)庫中。
  4. 最后,代碼再次刪除 Redis 中的緩存數(shù)據(jù)。這里是延遲雙刪的關(guān)鍵步驟。由于之前已經(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ù)從緩存中刪除,可能導(dǎo)致緩存和數(shù)據(jù)庫中的數(shù)據(jù)不一致。

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

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

在延時雙刪策略中,當(dāng)需要更新數(shù)據(jù)庫中的數(shù)據(jù)時,首先會先刪除緩存,然后再進(jìn)行數(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ù)庫的讀取壓力,提高讀取性能和響應(yīng)速度。

5、方案選擇

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

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

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

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

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

6、延時雙刪真的完美嗎

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

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

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

首先,**為什么要執(zhí)行第一次刪除緩存的操作?**這是因為在并發(fā)環(huán)境下,如果直接更新數(shù)據(jù)庫而不刪除緩存,會導(dǎo)致臟數(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í)行第一次刪除緩存的操作會帶來一定的資源開銷,但通過合理設(shè)置延遲時間和優(yōu)化緩存策略,可以在高并發(fā)讀取場景下,有效降低對數(shù)據(jù)庫的直接讀取次數(shù),從而提高讀取性能和并發(fā)性能。這樣在一段時間內(nèi),仍能從緩存中獲取數(shù)據(jù),減少數(shù)據(jù)庫壓力,而在數(shù)據(jù)庫更新完成后,再次刪除緩存以確保最終的數(shù)據(jù)一致性。

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

第一次刪除緩存的操作是為了以一定的資源開銷為代價,讓緩存中的舊數(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ā)讀取壓力。同時,因為緩存的更新是延遲進(jìn)行的,所以在一定時間內(nèi),讀取請求會持續(xù)從緩存中獲取數(shù)據(jù),而不會頻繁訪問數(shù)據(jù)庫,從而提高了讀取性能和響應(yīng)速度。

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

7、如何確定延時的時間

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

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

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

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

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

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

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

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

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

相關(guān)文章

  • 巧用Redis實(shí)現(xiàn)分布式鎖詳細(xì)介紹

    巧用Redis實(shí)現(xiàn)分布式鎖詳細(xì)介紹

    大家好,本篇文章主要講的是巧用Redis實(shí)現(xiàn)分布式鎖詳細(xì)介紹,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • redis執(zhí)行l(wèi)ua腳本的實(shí)現(xiàn)

    redis執(zhí)行l(wèi)ua腳本的實(shí)現(xiàn)

    本文主要介紹了redis執(zhí)行l(wèi)ua腳本的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-10-10
  • 使用攔截器+Redis實(shí)現(xiàn)接口冪思路詳解

    使用攔截器+Redis實(shí)現(xiàn)接口冪思路詳解

    這篇文章主要介紹了使用攔截器+Redis實(shí)現(xiàn)接口冪等,接口冪等有很多種實(shí)現(xiàn)方式,攔截器/AOP+Redis,攔截器/AOP+本地緩存等等,本文講解一下通過攔截器+Redis實(shí)現(xiàn)冪等的方式,需要的朋友可以參考下
    2023-08-08
  • Linux上安裝Redis詳細(xì)教程

    Linux上安裝Redis詳細(xì)教程

    這篇文章主要給大家詳細(xì)介紹了在Linux上安裝Redis詳細(xì)教程,文中有詳細(xì)的代碼示例和安裝步驟,對我們學(xué)習(xí)安裝redis有一定的幫助,需要的朋友可以參考下
    2023-07-07
  • Redis利用互斥鎖解決緩存擊穿問題

    Redis利用互斥鎖解決緩存擊穿問題

    使用互斥鎖可以有效防止緩存擊穿的情況發(fā)生,它能夠保證在緩存失效時,只有一個線程或者進(jìn)程能夠去加載數(shù)據(jù),其余的請求都會等待這個加載過程完成,雖然這種方式會犧牲一部分性能,但它大大提高了系統(tǒng)的穩(wěn)定性和可用性
    2024-08-08
  • mac下redis安裝、設(shè)置、啟動停止方法詳解

    mac下redis安裝、設(shè)置、啟動停止方法詳解

    這篇文章主要介紹了mac下redis安裝、設(shè)置、啟動停止方法詳解,需要的朋友可以參考下
    2020-02-02
  • 啟動redis出現(xiàn)閃退情況的解決辦法

    啟動redis出現(xiàn)閃退情況的解決辦法

    最近使用Redis遇到啟動閃退的問題,查閱資料后在一位大神的文章中找到了答案,這篇文章主要給大家介紹了關(guān)于啟動redis出現(xiàn)閃退情況的解決辦法,需要的朋友可以參考下
    2023-11-11
  • 淺談Redis阻塞的9種情況

    淺談Redis阻塞的9種情況

    本文主要介紹了淺談Redis阻塞的9種情況,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Redis分布式鎖的7種實(shí)現(xiàn)

    Redis分布式鎖的7種實(shí)現(xiàn)

    這篇文章主要介紹了Redis分布式鎖的實(shí)現(xiàn)
    2022-04-04
  • redis 替代php文件存儲session的實(shí)例

    redis 替代php文件存儲session的實(shí)例

    這篇文章主要介紹了redis 替代php文件存儲session的實(shí)例的相關(guān)資料,希望通過本文能幫助到大家,讓大家掌握這樣的方法,需要的朋友可以參考下
    2017-10-10

最新評論