国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

學懂緩存雪崩,緩存擊穿,緩存穿透僅需一篇,基于Redis講解

這篇具有很好參考價值的文章主要介紹了學懂緩存雪崩,緩存擊穿,緩存穿透僅需一篇,基于Redis講解。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

在了解緩存雪崩、擊穿、穿透這三個問題前,我們需要知道為什么我們需要緩存。在了解這三個問題后,我們也必須知道使用Redis時,如何解決這些問題。

所以我將按照"為什么我們需要緩存"、"什么是緩存雪崩、擊穿、穿透"、"如何解決這些問題"三部分,帶你學懂緩存雪崩、擊穿、穿透。

為什么我們需要緩存

用戶的數(shù)據(jù)一般都是存儲于數(shù)據(jù)庫,數(shù)據(jù)庫的數(shù)據(jù)是落在磁盤上的,磁盤的讀寫速度可以說是計算機里最慢的硬件了。當用戶的請求都訪問數(shù)據(jù)庫的話,可想而知,我們整個系統(tǒng)的并發(fā)量肯定是比較低的,而且如果一旦并發(fā)量上來了,數(shù)據(jù)庫也很容易崩潰。

那我們可以怎么樣來解決這個問題呢?

  • 我們可以多用幾臺機器,進行負載均衡,提高系統(tǒng)的并發(fā)量。

  • 也可以加一個中間層(緩存),避免用戶直接訪問數(shù)據(jù)庫。

  • ......

很顯然,使用緩存是比較簡單且經(jīng)濟的方案。其實,在現(xiàn)在的服務端開發(fā)中,緩存中間件已經(jīng)是我們所離不開的了。其中Redis就是比較著名的key-value內(nèi)存數(shù)據(jù)庫。故本文章基于Redis編寫。

學懂緩存雪崩,緩存擊穿,緩存穿透僅需一篇,基于Redis講解

什么是緩存雪崩、擊穿、穿透

緩存雪崩

通常我們?yōu)榱吮WC緩存中的數(shù)據(jù)與數(shù)據(jù)庫中的數(shù)據(jù)一致性,會給 Redis 里的數(shù)據(jù)設置過期時間,當緩存數(shù)據(jù)過期后,用戶訪問的數(shù)據(jù)如果不在緩存里,業(yè)務系統(tǒng)需要重新生成緩存,因此就會訪問數(shù)據(jù)庫,并將數(shù)據(jù)更新到 Redis 里,這樣后續(xù)請求都可以直接命中緩存。

這樣的流程乍一看很正確,沒有任何問題。實際上隱藏著一些問題,這樣做將可能導致有大量的key在同一時間失效,如果此時有大量的用戶請求,那就會去訪問數(shù)據(jù)庫,從而導致數(shù)據(jù)庫的壓力驟增,如果數(shù)據(jù)庫頂不住當前的壓力,則會導致宕機,進而引起一系列問題,最后導致系統(tǒng)崩潰,這就是緩存雪崩。

引發(fā)緩存雪崩有以下幾種可能:

  • 大量key同時失效
  • 充當緩存的Redis宕機了

緩存擊穿

我們的業(yè)務通常會有幾個數(shù)據(jù)會被頻繁地訪問,比如秒殺活動,這類被頻地訪問的數(shù)據(jù)被稱為熱點數(shù)據(jù)。如果熱點key在某個時間過期了,此時大量請求會打到數(shù)據(jù)庫上,數(shù)據(jù)庫很容易被擊穿,這就是緩存擊穿。

實際上緩存擊穿與緩存穿透都是key失效的問題,你也可以認為緩存擊穿是緩存穿透的子集。

學懂緩存雪崩,緩存擊穿,緩存穿透僅需一篇,基于Redis講解

緩存穿透

緩存雪崩和擊穿都是key失效或者Redis不可用的場景,緩存穿透與它們不同。緩存穿透是當用戶訪問的數(shù)據(jù),既不在緩存中,也不在數(shù)據(jù)庫中,導致請求在訪問緩存時,發(fā)現(xiàn)緩存缺失,再去訪問數(shù)據(jù)庫時,發(fā)現(xiàn)數(shù)據(jù)庫中也沒有要訪問的數(shù)據(jù),沒辦法構建緩存數(shù)據(jù),來服務后續(xù)的請求。那么當有大量這樣的請求到來時,數(shù)據(jù)庫的壓力驟增。

發(fā)生的原因有:

  • 業(yè)務操作錯誤,緩存的數(shù)據(jù)或數(shù)據(jù)庫的數(shù)據(jù)被刪除,或者意外被用戶訪問到不存在的數(shù)據(jù)
  • 黑客惡意攻擊

如何應對

緩存雪崩應對

緩存雪崩有兩種誘因,不同誘因應對的策略是不同的。

針對大量數(shù)據(jù)同時過期:

  • 均勻設置過期時間
  • 互斥鎖
  • 后臺更新緩存
  • ......

1.均勻設置過期時間

目的是要避免大量數(shù)據(jù)設置成同時過期。給這些設置了過期時間的key加上一個隨機數(shù),讓他們盡量不同時過期。尤其是在緩存預熱的時候,更需要這樣做。

2.互斥鎖

當業(yè)務線程在處理用戶請求時,如果發(fā)現(xiàn)訪問的數(shù)據(jù)不在Redis里,就加一個互斥鎖(setnx命令可以達到這個效果),保證同一個時間內(nèi)只有一個請求來構建緩存(從數(shù)據(jù)庫中讀,再更新到Redis),構建完后釋放鎖,未能獲取到鎖的請求,要么等鎖釋放后重新讀取緩存,要么返回空或默認值。

 

java

復制代碼

public class RedisTool { private static final String LOCK_SUCCESS = "OK"; private static final String SET_IF_NOT_EXIST = "NX"; private static final String SET_WITH_EXPIRE_TIME = "PX"; /** * 嘗試獲取分布式鎖 * @param jedis Redis客戶端 * @param lockKey 鎖 * @param requestId 請求標識 * @param expireTime 超期時間 * @return 是否獲取成功 */ public static boolean tryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) { String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime); if (LOCK_SUCCESS.equals(result)) { return true; } return false; } }

第一個為key,我們使用key來當鎖,因為key是唯一的。

第二個為value,我們傳的是requestId,很多童鞋可能不明白,有key作為鎖不就夠了嗎,為什么還要用到value?分布式鎖有一個條件,誰上的鎖就必須誰解開,通過給value賦值為requestId,我們就知道這把鎖是哪個請求加的了,在解鎖的時候就可以有依據(jù)。requestId可以使用多種方法生成,只要能保證在一段時間內(nèi)不重復。

第三個為nxxx,這個參數(shù)我們填的是NX,意思是SET IF NOT EXIST,即當key不存在時,我們進行set操作;若key已經(jīng)存在,則不做任何操作;

第四個為expx,這個參數(shù)我們傳的是PX,意思是我們要給這個key加一個過期的設置,具體時間由第五個參數(shù)決定。

第五個為time,與第四個參數(shù)相呼應,代表key的過期時間。

總的來說,執(zhí)行上面的set()方法就只會導致兩種結果:1. 當前沒有鎖(key不存在),那么就進行加鎖操作,并對鎖設置個有效期,同時value表示加鎖的客戶端。2. 已有鎖存在,不做任何操作。

不過這種方法就要注意一下死鎖問題,然后我代碼這樣寫的原因是,只有一個操作,是原子性的,如果把加鎖和設置過期時間分開,可能會發(fā)生一些意想不到的問題。

3.后臺更新緩存

業(yè)務線程不再負責更新緩存,緩存也不設置有效期,而是讓緩存“永久有效”,并將更新緩存的工作交由后臺線程定時更新。雖然不設置有效期,但是其實有一個邏輯過期的標識,一旦業(yè)務線程發(fā)現(xiàn)這個緩存過期,就把它交給后臺線程去處理。業(yè)務線程返回”過期值“。

這種方法適合用于對于緩存一致性要求不會特別嚴格的場景

針對Redis宕機:

  • 服務熔斷或進行請求限流
  • 構建Redis主從或集群來保證可靠

1.服務熔斷或進行請求限流

暫停業(yè)務,直接返回錯誤。等Redis恢復正常后,再允許業(yè)務進行。目的是保護數(shù)據(jù)庫。

也可以啟用限流,只允許少部分請求訪問數(shù)據(jù)庫,大于能承受的壓力的請求直接拒絕服務。等到Redis正常且預熱完畢,再解除限流。

2.構建Redis主從和哨兵或集群

主從能夠分擔主節(jié)點壓力,有了哨兵的話,能夠在Redis主節(jié)點故障時,即使切換主節(jié)點,避免Redis故障導致的緩存雪崩問題。

Redis集群(cluster)也是同理。

緩存擊穿應對

上面提到緩存擊穿是緩存雪崩的子集(數(shù)據(jù)過期導致的)

所以緩存擊穿的解決方法與因為數(shù)據(jù)過期導致的雪崩基本一致,可以采用:

  • 互斥鎖方案(與上面講的相同)
  • 后臺更新緩存方案(與上面講的相同)

緩存穿透應對

應對緩存穿透的方案,常見的方案有三種:

  • 非法請求的限制
  • 緩存空值或者默認值
  • 使用布隆過濾器快速判斷數(shù)據(jù)是否存在,避免通過查詢數(shù)據(jù)庫來判斷數(shù)據(jù)是否存在

1.非法請求的限制

當不用訪問數(shù)據(jù)庫就能知道請求的數(shù)據(jù)是否合法時,這個方式很合適??梢灾苯釉?strong>API的入口處做判斷,避免非法請求訪問緩存和數(shù)據(jù)庫

2.緩存空值

當我們線上業(yè)務發(fā)現(xiàn)緩存穿透的現(xiàn)象時,可以針對查詢的數(shù)據(jù),在緩存中設置一個空值或者默認值,這樣后續(xù)請求就可以從緩存中讀取到空值或者默認值,返回給應用,而不會繼續(xù)查詢數(shù)據(jù)庫。

要注意緩存的空值必須設置合適的過期時間,太短則會導致緩存沒有阻擋住大多數(shù)的非法請求,太長則會導致浪費內(nèi)存空間。

3.使用布隆過濾器快速判斷數(shù)據(jù)是否存在,避免通過查詢數(shù)據(jù)庫來判斷數(shù)據(jù)是否存在

我們可以在寫入數(shù)據(jù)庫數(shù)據(jù)時,使用布隆過濾器做個標記,然后在用戶請求到來時,業(yè)務線程確認緩存失效后,可以通過查詢布隆過濾器快速判斷數(shù)據(jù)是否存在,如果不存在,就不用通過查詢數(shù)據(jù)庫來判斷數(shù)據(jù)是否存在。

可能有部分童鞋不了解布隆過濾器,我簡單的描述一下。

布隆過濾器由「初始值都為 0 的位圖數(shù)組」和「 N 個哈希函數(shù)」兩部分組成。當我們在寫入數(shù)據(jù)庫數(shù)據(jù)時,在布隆過濾器里做個標記(對N個哈希函數(shù)逐一進行使用,得到的結果對數(shù)組長度取余得到最后結果,并且把最后結果對應的下標值為1)。下次查詢數(shù)據(jù)在不在數(shù)據(jù)庫時,可以用相同的方法,如果得到N個位置的值都為1,則這個請求大概率是合法的(即使會有部分非法請求還是會訪問到數(shù)據(jù)庫,但是布隆過濾器已經(jīng)過濾了絕大多數(shù)了)

學懂緩存雪崩,緩存擊穿,緩存穿透僅需一篇,基于Redis講解

總結


在網(wǎng)上找到的這張表格對上述內(nèi)容進行了不錯的總結。

學懂緩存雪崩,緩存擊穿,緩存穿透僅需一篇,基于Redis講解文章來源地址http://www.zghlxwxcb.cn/news/detail-464973.html

到了這里,關于學懂緩存雪崩,緩存擊穿,緩存穿透僅需一篇,基于Redis講解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • Redis緩存穿透,雪崩,擊穿

    1、定義 緩存 就是數(shù)據(jù)交換的 緩沖區(qū) ,緩存就是 緩沖區(qū)內(nèi)的數(shù)據(jù) ,一般從數(shù)據(jù)庫中獲取,存儲于本地代碼。 由于其被 Static 修飾,所以隨著類的加載而被加載到 內(nèi)存之中 ,作為本地緩存,由于其又被 final 修飾,所以其引用和對象之間的關系是固定的,不能改變,因此不用擔心賦值(=

    2024年02月10日
    瀏覽(22)
  • Redis之緩存穿透+緩存雪崩+緩存擊穿

    Redis之緩存穿透+緩存雪崩+緩存擊穿

    在生產(chǎn)環(huán)境中,會因為很多的原因造成訪問請求繞過了緩存,都需要訪問數(shù)據(jù)庫持久層,雖然對Redsi緩存服務器不會造成影響,但是數(shù)據(jù)庫的負載就會增大,使緩存的作用降低 ??緩存穿透是指查詢一個根本不存在的數(shù)據(jù),緩存層和持久層都不會命中。在日常工作中出于容錯

    2023年04月09日
    瀏覽(24)
  • Redis的緩存穿透,緩存擊穿,緩存雪崩

    Redis的緩存穿透,緩存擊穿,緩存雪崩

    什么是緩存穿透? 緩存穿透說簡單點就是大量請求的 key 是不合理的, 根本不存在于緩存中,也不存在于數(shù)據(jù)庫中 。這就導致這些請求直接到了數(shù)據(jù)庫上,根本沒有經(jīng)過緩存這一層,對數(shù)據(jù)庫造成了巨大的壓力,可能直接就被這么多請求弄宕機了。 eg:某個黑客故意制造一

    2024年02月10日
    瀏覽(20)
  • 68、Redis:緩存雪崩、緩存穿透、緩存擊穿

    緩存雪崩是指緩存同一時間大面積的失效,所以,后面的請求都會落到數(shù)據(jù)庫上,造成數(shù)據(jù)庫短時間內(nèi)承受大量請求而崩掉。 緩存數(shù)據(jù)的過期時間設置隨機,防止同一時間大量數(shù)據(jù)過期現(xiàn)象發(fā)生 給每一個緩存數(shù)據(jù)增加相應的緩存標記,記錄緩存是否失效,如果緩存標記失效

    2024年02月16日
    瀏覽(22)
  • Redis 緩存預熱+緩存雪崩+緩存擊穿+緩存穿透

    Redis 緩存預熱+緩存雪崩+緩存擊穿+緩存穿透

    面試題: 緩存預熱、雪萌、穿透、擊穿分別是什么?你遇到過那幾個情況? 緩存預熱你是怎么做的? 如何造免或者減少緩存雪崩? 穿透和擊穿有什么區(qū)別?他兩是一個意思還是載然不同? 穿適和擊穿你有什么解決方案?如何避免? 假如出現(xiàn)了緩存不一致,你有哪些修補方

    2024年02月10日
    瀏覽(20)
  • Redis緩存預熱-緩存穿透-緩存雪崩-緩存擊穿

    Redis緩存預熱-緩存穿透-緩存雪崩-緩存擊穿

    什么叫緩存穿透? 模擬一個場景: 前端用戶發(fā)送請求獲取數(shù)據(jù),后端首先會在緩存Redis中查詢,如果能查到數(shù)據(jù),則直接返回.如果緩存中查不到數(shù)據(jù),則要去數(shù)據(jù)庫查詢,如果數(shù)據(jù)庫有,將數(shù)據(jù)保存到Redis緩存中并且返回用戶數(shù)據(jù).如果數(shù)據(jù)庫沒有則返回null; 這個緩存穿透的問題就是這個

    2024年03月09日
    瀏覽(29)
  • Redis(緩存預熱,緩存雪崩,緩存擊穿,緩存穿透)

    Redis(緩存預熱,緩存雪崩,緩存擊穿,緩存穿透)

    目錄 一、緩存預熱 二、緩存雪崩 三、緩存擊穿 四、緩存穿透 ? 開過車的都知道,冬天的時候啟動我們的小汽車之后不要直接駕駛,先讓車子發(fā)動機預熱一段時間再啟動。緩存預熱是一樣的道理。 緩存預熱就是系統(tǒng)啟動前,提前將相關的緩存數(shù)據(jù)直接加載到緩存系統(tǒng)。避免

    2024年02月10日
    瀏覽(36)
  • Redis 緩存穿透擊穿和雪崩

    Redis 緩存穿透擊穿和雪崩

    ???????? Redis 緩存的使用,極大的提升了應用程序的性能和效率,特別是數(shù)據(jù)查詢方面。但同時,它也帶來了一些問題。其中,最要害的問題,就是數(shù)據(jù)的一致性問題,從嚴格意義上講,這個問題無解。如果對數(shù)據(jù)的一致性要求很高,那么就不能使用緩存。 2.1 概念 ???

    2024年02月10日
    瀏覽(33)
  • redis緩存雪崩、穿透和擊穿

    redis緩存雪崩、穿透和擊穿

    緩存雪崩 ? 對于系統(tǒng) A,假設每天高峰期每秒 5000 個請求,本來緩存在高峰期可以扛住每秒 4000 個請求,但是緩存機器意外發(fā)生了全盤宕機或者大量緩存集中在某一個時間段失效。緩存掛了,此時 1 秒 5000 個請求全部落數(shù)據(jù)庫,數(shù)據(jù)庫必然扛不住,它會報一下警,然后就掛了

    2024年01月22日
    瀏覽(19)
  • Redis 緩存雪崩、穿透、擊穿、預熱

    Redis 緩存雪崩、穿透、擊穿、預熱

    ????????在實際工程中,Redis 緩存問題常伴隨高并發(fā)場景出現(xiàn)。例如, 電商大促、活動報名、突發(fā)新聞 時,由于緩存失效導致大量請求訪問數(shù)據(jù)庫,導致 雪崩 、 擊穿 、 穿透 等問題。因此,新系統(tǒng)上線前需 預熱 緩存,以應對高并發(fā),減輕數(shù)據(jù)庫壓力。本章主要圍繞這

    2024年04月12日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包