自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Redis:緩存穿透、緩存擊穿、緩存雪崩?

數(shù)據(jù)庫(kù) Redis
正常情況下,一個(gè)請(qǐng)求過來,首先判斷key是否存在,如果key存在,直接返回;如果key不存在或者已過期,查詢數(shù)據(jù)庫(kù),如果數(shù)據(jù)庫(kù)中存在數(shù)據(jù),則更新緩存并返回?cái)?shù)據(jù);如果不存在,則直接返回空。

為什么要使用緩存

我們做的每一個(gè)項(xiàng)目基本上剛開始都是一個(gè)很小的項(xiàng)目,每天的QPS很少,那個(gè)時(shí)候系統(tǒng)訪問都是直接請(qǐng)求到數(shù)據(jù)庫(kù);后來項(xiàng)目越來越大,使用的人越來越多,每天對(duì)于數(shù)據(jù)庫(kù)的壓力劇增,為了保證“有效、有限的請(qǐng)求”訪問到數(shù)據(jù)庫(kù),我們放大前置環(huán)節(jié)的邏輯和成本,所以緩存應(yīng)運(yùn)而生。

緩存的好處有以下兩點(diǎn):

  • 提高接口的響應(yīng)時(shí)間和并發(fā)量;
  • 減輕數(shù)據(jù)庫(kù)的壓力。

但是,我們用到了緩存,就不得不考慮三個(gè)經(jīng)典的場(chǎng)景:“緩存穿透”、“緩存擊穿”、“緩存雪崩”。本文將介紹三種場(chǎng)景并給出合理的解決方案,如有異議,請(qǐng)進(jìn)行友好的評(píng)論。

緩存穿透

正常情況下,一個(gè)請(qǐng)求過來,首先判斷key是否存在,如果key存在,直接返回;如果key不存在或者已過期,查詢數(shù)據(jù)庫(kù),如果數(shù)據(jù)庫(kù)中存在數(shù)據(jù),則更新緩存并返回?cái)?shù)據(jù);如果不存在,則直接返回空。

緩存穿透(cache penetration)是用戶訪問的key在數(shù)據(jù)庫(kù)中一定不存在的數(shù)據(jù),如果有人利用這個(gè)漏洞惡意系統(tǒng),每次請(qǐng)求的壓力都給到數(shù)據(jù)庫(kù),會(huì)壓垮數(shù)據(jù)庫(kù),造成系統(tǒng)崩潰。

方案一:緩存默認(rèn)值

在數(shù)據(jù)庫(kù)查詢不存在時(shí),可以將其緩存為默認(rèn)值。不過設(shè)置的時(shí)間不宜過長(zhǎng)(建議設(shè)置為60s),如果過了一會(huì)兒數(shù)據(jù)庫(kù)新增了該數(shù)據(jù),時(shí)間太長(zhǎng)的話,就會(huì)出現(xiàn)數(shù)據(jù)不一致的情況。

方案二:業(yè)務(wù)邏輯前置判斷

如果有人為的惡意打擊,用不合理的參數(shù)去請(qǐng)求系統(tǒng),按照方案一新增了大量的不存在的key到內(nèi)存中,極端情況下,緩存也被撐爆了……

所以我們可以在接口處進(jìn)行數(shù)據(jù)合法性校驗(yàn),進(jìn)行提前拒絕。比如:a接口只允許查詢18+的成年人的數(shù)據(jù),請(qǐng)求帶有未成年人就明顯不合適。

方案三:使用布隆過濾器

如果有人很巧妙的用合理的參數(shù)但是系統(tǒng)內(nèi)不存在的key請(qǐng)求系統(tǒng),系統(tǒng)按照方案一、方案二也會(huì)新增大量的不存在key到內(nèi)存中,這時(shí)又怎么辦呢……

那我們可以使用布隆過濾器(本文不做擴(kuò)展哈,請(qǐng)自行了解),當(dāng)把數(shù)據(jù)寫入數(shù)據(jù)庫(kù)的時(shí)候,使用布隆過濾器進(jìn)行標(biāo)記,當(dāng)有請(qǐng)求時(shí),如果發(fā)現(xiàn)緩存消失,在去查詢數(shù)據(jù)庫(kù)前,先查詢布隆過濾器該key是否存在,如果不存在,直接返回,不過布隆過濾器有一定的誤判率,這個(gè)可以忽略。

方案四:加互斥鎖或隊(duì)列

經(jīng)過方案一、二、三的優(yōu)化,應(yīng)該可以處理穿透的問題吧,但是仔細(xì)想一想,兄弟兒,我們是高并發(fā)的場(chǎng)景啊,所以,場(chǎng)景是大量的請(qǐng)求同一時(shí)刻都來請(qǐng)求同一個(gè)key,發(fā)現(xiàn)沒有這個(gè)key,全都去訪問數(shù)據(jù)庫(kù),以至于系統(tǒng)崩潰……

在這里,我們要加一個(gè)鎖,只保證一個(gè)線程去創(chuàng)建緩存,其余的等待,這樣就ok了。

緩存擊穿

緩存擊穿(Cache Breakdown)指的是一個(gè)熱點(diǎn)key,在不停的被大量的請(qǐng)求訪問,當(dāng)這個(gè)熱點(diǎn)key緩存失效的瞬間,大量的請(qǐng)求訪問到數(shù)據(jù)庫(kù),以至于系統(tǒng)崩潰。

方案一:永不過期

提前把熱點(diǎn)數(shù)據(jù)不設(shè)置過期時(shí)間,后臺(tái)異步更新緩存。

但是!我又要說但是了!我現(xiàn)在舉個(gè)例子,就要推翻這個(gè)方案了,打自己的臉。

我們自家的甲秀寶商城最近3月8日女神節(jié)做一次大促,把運(yùn)營(yíng)童鞋收集整理的關(guān)于女性熱點(diǎn)商品都做了永不過期,但是大促當(dāng)天發(fā)現(xiàn)面巾紙是賣的最多的,差點(diǎn)就要祭天了……

所以,真實(shí)場(chǎng)景是就像你根本無(wú)法知道女朋友想什么一樣,同理你也不能真正的預(yù)估到客戶想買什么,哪個(gè)是熱點(diǎn)商品,所以,這個(gè)方案也就是面試吹吹……

方案二:加互斥鎖或隊(duì)列

其實(shí)我理解緩存擊穿和緩存穿透差不多,所以加一個(gè)互斥鎖,讓一個(gè)線程正常請(qǐng)求數(shù)據(jù)庫(kù),其他線程等待即可(這里可以使用線程池來處理),都創(chuàng)建完緩存,讓其他線程請(qǐng)求緩存即可。

緩存雪崩

緩存雪崩(Cache Avalanche)指的是當(dāng)某一個(gè)時(shí)刻出現(xiàn)大規(guī)模的緩存失效,然后大量的請(qǐng)求直接訪問到數(shù)據(jù)庫(kù),以至于壓垮數(shù)據(jù)庫(kù),造成系統(tǒng)崩潰等情況。

出現(xiàn)這種情況的可能有兩種:

  • 緩存采用相同的過期時(shí)間。
  • 緩存服務(wù)出現(xiàn)故障。

方案一:相對(duì)隨機(jī)數(shù)過期時(shí)間

key的過期時(shí)間加上一個(gè)隨機(jī)值,保證不是同一時(shí)間失效,即可。

方案二:分布式集群部署

單節(jié)點(diǎn)緩存服務(wù)容易宕機(jī),那我們就部署個(gè)集群,然后把緩存均勻的分不到不同的服務(wù)器上,搞定。

方案三:服務(wù)限流、熔斷、降級(jí)

當(dāng)流量到一定的閾值或者服務(wù)出現(xiàn)異常、故障時(shí),直接返回“請(qǐng)稍后再試”的友好性處理,讓一部分用戶正常使用,其他用戶多重試幾次,不過這樣難免會(huì)降低用戶體驗(yàn),不過幾個(gè)人有問題也總比整個(gè)系統(tǒng)崩潰好~

END

緩存穿透、緩存擊穿、緩存雪崩,說白了核心就是“避免無(wú)效(或重復(fù))的請(qǐng)求”到數(shù)據(jù)庫(kù),所以我覺得只要是以這個(gè)思想去設(shè)計(jì)都是ok的~


責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2019-10-12 14:19:05

Redis數(shù)據(jù)庫(kù)緩存

2020-03-16 14:57:24

Redis面試雪崩

2021-06-05 09:01:01

Redis緩存雪崩緩存穿透

2022-03-08 00:07:51

緩存雪崩數(shù)據(jù)庫(kù)

2019-11-05 14:24:31

緩存雪崩框架

2023-04-14 07:34:19

2022-05-27 07:57:20

緩存穿透緩存雪崩緩存擊穿

2023-12-06 13:38:00

Redis緩存穿透緩存擊穿

2022-11-18 14:34:28

2023-11-10 14:58:03

2024-03-12 10:44:42

2024-04-18 11:43:28

緩存數(shù)據(jù)庫(kù)Redis

2024-04-07 00:00:02

Redis雪崩緩存

2020-10-13 07:44:40

緩存雪崩 穿透

2021-12-25 22:28:27

緩存穿透緩存擊穿緩存雪崩

2020-10-23 10:46:03

緩存雪崩擊穿

2022-07-11 07:36:36

緩存緩存雪崩緩存擊穿

2020-03-05 09:09:18

緩存原因方案

2020-12-28 12:37:36

緩存擊穿穿透

2023-01-31 08:37:11

緩存穿透擊穿
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)