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

Redis與緩存解讀

 更新時(shí)間:2025年01月10日 10:54:18   作者:knight-n  
文章介紹了Redis作為緩存層的優(yōu)勢和缺點(diǎn),并分析了六種緩存更新策略,包括超時(shí)剔除、先刪緩存再更新數(shù)據(jù)庫、旁路緩存、先更新數(shù)據(jù)庫再刪緩存、先更新數(shù)據(jù)庫再更新緩存、讀寫穿透和異步緩存寫入模式,還討論了緩存常見問題

緩存

在業(yè)務(wù)開發(fā)中,必然會(huì)存在需要頻繁訪問的數(shù)據(jù)即熱點(diǎn)數(shù)據(jù),如果通過訪問數(shù)據(jù)庫訪問這些數(shù)據(jù),由于數(shù)據(jù)存儲(chǔ)在磁盤上,在頻繁訪問下會(huì)進(jìn)行頻繁的IO操作,會(huì)導(dǎo)致數(shù)據(jù)庫壓力過大,響應(yīng)速度變慢。

那么我們可以在添加一層中間緩存層,將熱點(diǎn)數(shù)據(jù)緩存在內(nèi)存中,在訪問數(shù)據(jù)時(shí)我們不在直接查詢數(shù)據(jù)庫,而是先訪問緩存,如果數(shù)據(jù)存在(命中),直接返回即可。如果數(shù)據(jù)不存在(未命中),再訪問數(shù)據(jù)庫。

redis 將數(shù)據(jù)存儲(chǔ)在內(nèi)存中,因此可以提供接近于內(nèi)存的訪問速度。所以 redis 天然適合作為緩存層。

緩存并不是萬能的,實(shí)際上緩存更使用于讀密集場景,在寫密集場景中由于需要保證緩存于數(shù)據(jù)庫的一致性,在修改緩存時(shí)還需要修改數(shù)據(jù)庫,反而加重了后端壓力。

緩存優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

  • 降低后端負(fù)載
  • 提高讀寫效率,降低響應(yīng)時(shí)間

缺點(diǎn):

  • 增加數(shù)據(jù)一致性成本
  • 增加代碼維護(hù)成本

緩存更新策略

為了保證緩存數(shù)據(jù)有效,我們需要更新緩存。這里主要有六種緩存更新策略:

超時(shí)剔除

在 redis 中我們可以設(shè)置數(shù)據(jù)的生存時(shí)間(TTL),在超時(shí)后,redis會(huì)自動(dòng)刪除緩存,在下次查詢?cè)摂?shù)據(jù)時(shí),由于緩存不存在,會(huì)重新寫入緩存,完成更新。

這種方法實(shí)現(xiàn)簡單,但一致性一般,在緩存未過期之前,對(duì)數(shù)據(jù)庫的數(shù)據(jù)進(jìn)行增刪查改都不會(huì)影響緩存,用戶查到的數(shù)據(jù)始終是舊數(shù)據(jù)。

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

在對(duì)數(shù)據(jù)庫進(jìn)行更新時(shí),先刪除緩存,然后更新數(shù)據(jù),在下次查詢?cè)摂?shù)據(jù)時(shí),由于緩存不存在,會(huì)重新將新數(shù)據(jù)寫入緩存,完成更新。

這種方法也無法保證數(shù)據(jù)的一致性。假設(shè)有兩個(gè)線程,線程A 與 線程B , 在線程 A 更新緩存時(shí),線程 B 發(fā)起查詢,可能出現(xiàn)這種情況:

在這種情況下,一直到下次數(shù)據(jù)更新之前,緩存始終不一致,因此不推薦使用這種方法。

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

在更新數(shù)據(jù)時(shí),先更新數(shù)據(jù)庫,再刪除緩存,在下次查詢?cè)摂?shù)據(jù)時(shí),由于緩存不存在,會(huì)重新將新數(shù)據(jù)寫入緩存,完成更新。

這種方法同樣無法完全保證數(shù)據(jù)的一致性,但他是最常用的更新策略。因?yàn)樗l(fā)生問題的概況較小,假設(shè)有兩個(gè)線程,線程A 與 線程B , 在線程 B 更新數(shù)據(jù)庫時(shí),線程 A 發(fā)起查詢,可能出現(xiàn)這種情況:

同樣這種情況會(huì)出現(xiàn)數(shù)據(jù)不一致問題,但這種情況出現(xiàn)概率非常小,出現(xiàn)這種情況需要至少滿足四個(gè)條件:

  • 讀操作所讀數(shù)據(jù)緩存失效
  • 有個(gè)并發(fā)的寫操作
  • 寫操作比讀操作更快
  • 讀操作早于寫操作進(jìn)入數(shù)據(jù)庫,晚于寫操作更新緩存

這樣的條件是十分苛刻的,即使發(fā)生也是小概率事件,即使出現(xiàn)也可以通過緩存生存時(shí)間兜底。

這種方法最大的問題是刪除緩存后的并發(fā)問題即緩存擊穿問題,在緩存常見問題我們會(huì)介紹。

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

在更新數(shù)據(jù)時(shí),先更新數(shù)據(jù)庫,再更新緩存。

理論上這種方式比先更新數(shù)據(jù)庫再刪緩存有著更高的讀性能,因?yàn)樗孪葴?zhǔn)備好數(shù)據(jù)。但由于要更新數(shù)據(jù)庫和緩存兩塊數(shù)據(jù),所以它的寫性能就比較低,同時(shí)他也不能完全保證數(shù)據(jù)的一致性。

假設(shè)有兩個(gè)線程,線程A 與 線程B , 在線程 A B 同時(shí)更新,可能出現(xiàn)這種情況:

讀寫穿透

客戶端只與緩存交互,緩存負(fù)責(zé)與數(shù)據(jù)庫的交互。

讀操作先查詢緩存,如果緩存未命中,則緩存從數(shù)據(jù)庫加載數(shù)據(jù)并寫入緩存。寫操作是直接寫緩存,然后緩存同步更新數(shù)據(jù)庫。這種模式下,緩存和數(shù)據(jù)庫的一致性由緩存中間件維護(hù)。

異步緩存寫入模式

客戶端只與緩存交互,緩存異步地將數(shù)據(jù)更新到數(shù)據(jù)庫,實(shí)現(xiàn)最終一致性。

這種模式適用于寫操作頻繁的場景,但可能會(huì)導(dǎo)致數(shù)據(jù)一致性問題。

緩存常見問題

使用緩存比較常見的問題有下面三種問題:緩存擊穿,緩存雪崩,緩存穿透。

緩存穿透

在我們的業(yè)務(wù)邏輯中,如果客戶端訪問的數(shù)據(jù)不存在于緩存我們會(huì)訪問數(shù)據(jù)庫,如果數(shù)據(jù)庫存在數(shù)據(jù)就寫入緩存,如果不存在就返回,那么如果客戶端不懷好意,頻繁發(fā)起對(duì)不存在數(shù)據(jù)的請(qǐng)求會(huì)發(fā)生什么呢?大量請(qǐng)求會(huì)直接打入數(shù)據(jù)庫,增大后端壓力,實(shí)現(xiàn)對(duì)服務(wù)器的攻擊。

解決方案有很多種,最常見的有兩種方法:緩存空對(duì)象,布隆過濾器。

緩存空對(duì)象:當(dāng)請(qǐng)求的數(shù)據(jù)在數(shù)據(jù)庫中不存在時(shí),我們將這個(gè)“不存在”的結(jié)果緩存起來,設(shè)置一個(gè)較短的過期時(shí)間。 這樣,相同的請(qǐng)求在緩存失效之前會(huì)直接命中緩存,減輕數(shù)據(jù)庫的壓力。

布隆過濾器:使用布隆過濾器存儲(chǔ)所有可能查詢的鍵,當(dāng)請(qǐng)求到達(dá)時(shí),先通過布隆過濾器判斷鍵是否存在。如果布隆過濾器認(rèn)為鍵不存在,則直接返回,不進(jìn)行數(shù)據(jù)庫查詢和緩存操作。

緩存雪崩

緩存雪崩是指在高并發(fā)系統(tǒng)中,大量的緩存數(shù)據(jù)在同一時(shí)間過期或被清除,導(dǎo)致大量請(qǐng)求同時(shí)涌向數(shù)據(jù)庫,從而對(duì)數(shù)據(jù)庫造成巨大壓力,甚至可能導(dǎo)致數(shù)據(jù)庫宕機(jī)。類似于“雪崩”。

常見的解決方法有以下幾種:

設(shè)置不同的過期時(shí)間: 對(duì)于緩存中的每個(gè)數(shù)據(jù)項(xiàng),設(shè)置不同的過期時(shí)間,這樣可以避免大量數(shù)據(jù)同時(shí)過期。例如,可以為每個(gè)數(shù)據(jù)項(xiàng)的過期時(shí)間加上一個(gè)隨機(jī)值。

使用互斥鎖: 當(dāng)緩存數(shù)據(jù)過期時(shí),如果多個(gè)請(qǐng)求同時(shí)到達(dá),使用互斥鎖確保只有一個(gè)請(qǐng)求去查詢數(shù)據(jù)庫并更新緩存,其他請(qǐng)求等待或重試。

熱點(diǎn)數(shù)據(jù)永不過期: 對(duì)于訪問非常頻繁的熱點(diǎn)數(shù)據(jù),可以考慮設(shè)置為永不過期,或者設(shè)置一個(gè)非常長的過期時(shí)間。

緩存擊穿

在高并發(fā)的訪問下,當(dāng)某個(gè)熱點(diǎn)數(shù)據(jù)緩存處于過期失效的時(shí)間點(diǎn)時(shí),極有可能出現(xiàn)多個(gè)線程同時(shí)查詢?cè)摼彺?。而查詢?shù)據(jù)庫更新緩存又需要消耗一定時(shí)間,在同一時(shí)間會(huì)有大量并發(fā)請(qǐng)求直接訪問數(shù)據(jù)庫而導(dǎo)致數(shù)據(jù)庫服務(wù)器的CPU或者內(nèi)存負(fù)載過高,服務(wù)能力下降甚至宕機(jī)。

那么如何解決這個(gè)問題呢?有三種解決方案。

  • 加鎖:在緩存失效后,通過加鎖的方式只允許一個(gè)線程查詢數(shù)據(jù)和寫緩存,其他線程阻塞等待。這個(gè)方法會(huì)造成部分請(qǐng)求等待。
  • 二級(jí)緩存:A1為原始緩存,A2為拷貝緩存。A1失效時(shí),可以訪問A2,其中A1的緩存失效時(shí)間設(shè)置為短期(比如5min),A2的緩存失效時(shí)間設(shè)置為長期(比如1天)。如果緩存value很大,此方案的緩存空間利用率低。
  • 雙key:思路和方案2類似,不同的是雙key分別緩存過期時(shí)間(key-time)和緩存數(shù)據(jù)(key-data),其中(key-time)的緩存失效時(shí)間設(shè)置為短期(比如5min),(key-data)的緩存失效時(shí)間設(shè)置為長期(比如1天)。當(dāng)?shù)谝粋€(gè)線程發(fā)現(xiàn) key-time 過期不存在時(shí),則先更新key-time,然后去查詢數(shù)據(jù)庫并更新key-data 的值;當(dāng)其他線程來獲取數(shù)據(jù)時(shí),雖然第一個(gè)線程還沒有從數(shù)據(jù)庫查詢完畢并更新緩存,但發(fā)現(xiàn)key-time存在,會(huì)直接讀取緩存的舊數(shù)據(jù)返回。和二級(jí)緩存的方案對(duì)比,該方案的緩存空間利用率高。

總結(jié)

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

相關(guān)文章

  • Redis如何實(shí)現(xiàn)延遲隊(duì)列

    Redis如何實(shí)現(xiàn)延遲隊(duì)列

    這篇文章主要介紹了Redis如何實(shí)現(xiàn)延遲隊(duì)列問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Redis配置文件redis.conf詳細(xì)配置說明

    Redis配置文件redis.conf詳細(xì)配置說明

    本文列出了Redis的配置文件redis.conf的各配置項(xiàng)的詳細(xì)說明,簡單易懂
    2018-03-03
  • Redis五大基本數(shù)據(jù)類型及對(duì)應(yīng)使用場景總結(jié)

    Redis五大基本數(shù)據(jù)類型及對(duì)應(yīng)使用場景總結(jié)

    Redis有五種基本數(shù)據(jù)類型,分別是字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted?Set),這些基本數(shù)據(jù)類型使得Redis具備了豐富的數(shù)據(jù)結(jié)構(gòu)和功能,適用于各種不同的應(yīng)用場景,本文就給大家詳細(xì)的介紹一下這五大類型
    2023-08-08
  • redis?lua限流算法實(shí)現(xiàn)示例

    redis?lua限流算法實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了redis?lua限流算法實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Redis3.2.6配置文件詳細(xì)中文說明

    Redis3.2.6配置文件詳細(xì)中文說明

    本文為大家分享了Redis3.2.6配置文件詳細(xì)中文說明,非常詳細(xì)收藏起來以后工作有用
    2018-10-10
  • redis 交集、并集、差集的具體使用

    redis 交集、并集、差集的具體使用

    這篇文章主要介紹了redis 交集、并集、差集的具體使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Redis Lua腳本的使用教程

    Redis Lua腳本的使用教程

    在Redis的學(xué)習(xí)中,Lua腳本是一項(xiàng)強(qiáng)大的高級(jí)特性,它允許用戶在Redis中執(zhí)行復(fù)雜的操作,本文就來介紹一下Redis Lua,腳本的使用教程,感興趣的可以了解一下
    2024-03-03
  • CentOS 7下安裝 redis 3.0.6并配置集群的過程詳解

    CentOS 7下安裝 redis 3.0.6并配置集群的過程詳解

    這篇文章主要給大家介紹了CentOS 7下安裝 redis 3.0.6并配置集群的過程,文中通過示例代碼和詳細(xì)的步驟介紹的很相信,對(duì)大家具有一定的參考價(jià)值,有需要的朋友們下面來一起看看吧。
    2017-01-01
  • Redis過期Key刪除策略和內(nèi)存淘汰策略的實(shí)現(xiàn)

    Redis過期Key刪除策略和內(nèi)存淘汰策略的實(shí)現(xiàn)

    當(dāng)內(nèi)存使用達(dá)到上限,就無法存儲(chǔ)更多數(shù)據(jù)了,為了解決這個(gè)問題,Redis內(nèi)部會(huì)有兩套內(nèi)存回收的策略,過期Key刪除策略和內(nèi)存淘汰策略,本文就來詳細(xì)的介紹一下這兩種方法,感興趣的可以了解一下
    2024-02-02
  • Redis中鍵和數(shù)據(jù)庫通用指令詳解

    Redis中鍵和數(shù)據(jù)庫通用指令詳解

    這篇文章主要為大家介紹了Redis中鍵和數(shù)據(jù)庫通用指令基本操作詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08

最新評(píng)論