Redis三種常用的緩存讀寫(xiě)策略步驟詳解
一、Redis三種常用的緩存讀寫(xiě)策略
Redis有三種讀寫(xiě)策略分別是:旁路緩存模式策略、讀寫(xiě)穿透策略、異步緩存寫(xiě)入策略。
這三種緩存讀寫(xiě)策略各有優(yōu)勢(shì),不存在最佳,需要我們根據(jù)實(shí)際的業(yè)務(wù)場(chǎng)景選擇最合適的。
二、旁路緩存模式(Cache Aside Pattern)
旁路緩存模式是我們平時(shí)使用比較多的一個(gè)緩存讀寫(xiě)模式,比較適合讀請(qǐng)求比較多的場(chǎng)景。
旁路緩存模式中服務(wù)端需要同時(shí)維護(hù)DB和Cache,并且是以DB的結(jié)果為準(zhǔn)。
讀寫(xiě)步驟
寫(xiě):
- 先更新
DB。 - 然后直接刪除
cache。
如下圖:

讀:
- 從
cache中讀取數(shù)據(jù),讀取到就直接返回。 cache中讀取不到的話,就從DB讀取返回。- 再把數(shù)據(jù)寫(xiě)到
cache中。
如下圖:

自我思考
思考這樣子的一個(gè)問(wèn)題:“如果在寫(xiě)數(shù)據(jù)的過(guò)程中,可以先刪除cache,再更新DB嗎? ”
答案: 答案肯定是不行的,因?yàn)檫@樣子可能造成數(shù)據(jù)庫(kù)和緩存數(shù)據(jù)不一致的問(wèn)題,比如這個(gè)時(shí)候有一個(gè)數(shù)據(jù)在DB和緩存都為100,請(qǐng)求1需要將這個(gè)數(shù)據(jù)更新寫(xiě)成200,如果先刪除換出再更新數(shù)據(jù)庫(kù)的話,在請(qǐng)求1已經(jīng)刪除緩存但是數(shù)據(jù)庫(kù)還沒(méi)寫(xiě)完的時(shí)候,有一個(gè)請(qǐng)求2讀取數(shù)據(jù),首先去緩存讀取,發(fā)現(xiàn)緩存被刪除了,然后去數(shù)據(jù)庫(kù)讀取得到100(這個(gè)時(shí)候請(qǐng)求1還沒(méi)寫(xiě)完)再寫(xiě)入緩存,這個(gè)時(shí)候請(qǐng)求1寫(xiě)完了,這個(gè)時(shí)候數(shù)據(jù)庫(kù)里數(shù)據(jù)為200,緩存里為100,不一致。
可以簡(jiǎn)單描述為:
請(qǐng)求1先把cache中的數(shù)據(jù)刪除 -> 請(qǐng)求2從DB中讀取數(shù)據(jù) -> 請(qǐng)求1再把DB中的數(shù)據(jù)更新
緊接著思考:“在寫(xiě)數(shù)據(jù)的過(guò)程中,如果先寫(xiě)B(tài)D,再刪除cache就不會(huì)造成數(shù)據(jù)不一致了嗎? ”
答案: 理論上來(lái)說(shuō)還是會(huì)出現(xiàn)數(shù)據(jù)不一致的問(wèn)題,不過(guò)概率很小,因?yàn)榫彺娴膶?xiě)入速度是比數(shù)據(jù)庫(kù)寫(xiě)入速度快很多。
比如請(qǐng)求1先讀數(shù)據(jù)A,請(qǐng)求2隨后寫(xiě)數(shù)據(jù)A,并且數(shù)據(jù)A不在緩存中存在的話就會(huì)去數(shù)據(jù)庫(kù)讀取,讀取完請(qǐng)求2再更新完并刪除緩存,然后請(qǐng)求1把數(shù)據(jù)A寫(xiě)入緩存,這個(gè)時(shí)候數(shù)據(jù)庫(kù)和緩存就不一致了。
這個(gè)過(guò)程可以簡(jiǎn)單的描述為:
請(qǐng)求1從DB讀取數(shù)據(jù)A -> 請(qǐng)求2寫(xiě)更新數(shù)據(jù)A到數(shù)據(jù)庫(kù)再刪除cache中的A數(shù)據(jù) -> 請(qǐng)求1將數(shù)據(jù)A寫(xiě)入緩存
缺點(diǎn)
首次請(qǐng)求的數(shù)據(jù)一定不在cache的問(wèn)題
解決辦法:可以將熱點(diǎn)數(shù)據(jù)提前寫(xiě)入
cache中。寫(xiě)操作比較頻繁的話導(dǎo)致cache中的數(shù)據(jù)會(huì)被頻繁的刪除,這樣會(huì)影響緩存命中率。
解決辦法:
- 數(shù)據(jù)庫(kù)和緩存強(qiáng)一直場(chǎng)景:更新
DB的時(shí)候同樣更新cache,不過(guò)需要加一個(gè)鎖/分布式鎖來(lái)保證更新cache的時(shí)候不存在線程安全問(wèn)題。 - 可以短暫的允許數(shù)據(jù)庫(kù)和緩存數(shù)據(jù)不一致的場(chǎng)景:更新
DB的時(shí)候同樣更新cache,但是給緩存加一個(gè)比較短的過(guò)期時(shí)間,這樣的話就可以保證即使數(shù)據(jù)不一致的話影響也比較小。
- 數(shù)據(jù)庫(kù)和緩存強(qiáng)一直場(chǎng)景:更新
三、讀寫(xiě)穿透(Read/Write Through Pattern)
讀寫(xiě)穿透中服務(wù)端把cache視為主要數(shù)據(jù)存儲(chǔ),從中讀取數(shù)據(jù)并將數(shù)據(jù)寫(xiě)入其中。cache服務(wù)負(fù)責(zé)將此數(shù)據(jù)讀取和寫(xiě)入DB,從而減輕應(yīng)用程序的職責(zé)。
讀寫(xiě)步驟
寫(xiě):
- 先查
cache,cache中不存在,直接更新DB。 cache中存在,則先更新cache,然后cache服務(wù)自己更新DB(同時(shí)更新DB和cache)。
如下圖:

讀:
- 先從
cache中讀取數(shù)據(jù),讀取到直接返回。 - 從
cache中讀取不到,則先從DB加載寫(xiě)入到cache后返回響應(yīng)。
如下圖:

讀寫(xiě)穿透實(shí)際是在旁路緩存之上進(jìn)行了封裝。在旁路緩存下,發(fā)生讀請(qǐng)求的時(shí)候,如果cache中不存在對(duì)應(yīng)的數(shù)據(jù),是由客戶端自己負(fù)責(zé)把數(shù)據(jù)寫(xiě)入cache,而讀寫(xiě)穿透則是cache服務(wù)自己來(lái)寫(xiě)入緩存,這對(duì)客戶端是透明的。
和旁路緩存一樣,讀寫(xiě)穿透也存在首次請(qǐng)求數(shù)據(jù)一定不在cache中的問(wèn)題,對(duì)于熱點(diǎn)數(shù)據(jù)可以提前寫(xiě)入緩存中。
四、異步緩存寫(xiě)入(Write Behind Pattern)
異步緩存寫(xiě)入和讀寫(xiě)穿透很相似,兩者都是由cache服務(wù)來(lái)負(fù)責(zé)cache和DB的讀寫(xiě)。
兩者最大的不同點(diǎn)就是:讀寫(xiě)穿透是同步更新DB和cache,而異步緩存寫(xiě)入則是只更新cache,不直接更新DB,而是改為異步批量的方式更新DB。
很明顯,這種方式對(duì)數(shù)據(jù)一致性帶來(lái)了更大的挑戰(zhàn),比如cache數(shù)據(jù)可能還沒(méi)異步更新DB,cache服務(wù)可能就掛了。
這種策略在我們平時(shí)開(kāi)發(fā)過(guò)程中也非常少見(jiàn),但是不代表它的應(yīng)用場(chǎng)景少,比如消息隊(duì)列中消息的異步寫(xiě)入磁盤(pán)、MySQL的InnoDB Buffer Pool機(jī)制都用到了這種策略。
異步緩存寫(xiě)入的寫(xiě)性能非常高,非常適合寫(xiě)數(shù)據(jù)經(jīng)常變化又對(duì)數(shù)據(jù)一致性要求沒(méi)那么高的場(chǎng)景下使用,比如瀏覽量、點(diǎn)贊量等。
到此這篇關(guān)于Redis三種常用的緩存讀寫(xiě)策略的文章就介紹到這了,更多相關(guān)Redis緩存讀寫(xiě)策略內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Redis?存儲(chǔ)對(duì)象信息用?Hash?和String的區(qū)別
這篇文章主要介紹了Redis存儲(chǔ)對(duì)象信息用Hash和String的區(qū)別,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09
RedisTemplate集成+封裝RedisUtil過(guò)程
本文介紹了如何搭建一個(gè)多模塊的Redis項(xiàng)目,包括項(xiàng)目搭建、配置和測(cè)試,通過(guò)使用父項(xiàng)目管理多個(gè)子模塊,可以實(shí)現(xiàn)單點(diǎn)構(gòu)建、統(tǒng)一版本管理和清晰的項(xiàng)目結(jié)構(gòu),文章還提供了在Spring Boot項(xiàng)目中集成RedisTemplate的示例,并解決了編碼問(wèn)題2024-12-12
關(guān)于redisson緩存序列化的幾枚大坑說(shuō)明
這篇文章主要介紹了redisson緩存序列化幾枚大坑,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
通過(guò)prometheus監(jiān)控redis實(shí)時(shí)運(yùn)行狀態(tài)的操作方法
本文詳細(xì)介紹了如何通過(guò)Prometheus監(jiān)控Redis的運(yùn)行狀態(tài),包括安裝配置Redis、Redis Exporter以及Prometheus,配置Prometheus監(jiān)控Redis指標(biāo),以及常見(jiàn)的Redis指標(biāo)和告警規(guī)則,需要的朋友可以參考下2025-02-02
Redis集群設(shè)置密碼訪問(wèn)的實(shí)現(xiàn)
本文檔介紹了在Redis集群上配置和管理密碼,包括為每個(gè)節(jié)點(diǎn)添加requirepass配置以啟用密碼保護(hù),及通過(guò)redis-cli關(guān)閉集群時(shí)使用密碼,感興趣的可以了解一下2025-08-08

