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

老大讓我設(shè)計(jì)億級(jí)系統(tǒng)的Redis緩存...

存儲(chǔ) 存儲(chǔ)軟件 Redis
緩存設(shè)計(jì)可謂老生常談了,早些時(shí)候都是采用 Memcache,現(xiàn)在大家更多傾向使用 Redis,除了知曉常用的數(shù)據(jù)存儲(chǔ)類(lèi)型,結(jié)合業(yè)務(wù)場(chǎng)景有針對(duì)性選擇,好像其他也沒(méi)有什么大的難點(diǎn)。

 [[403118]] 

圖片來(lái)自 Pexels

工程中引入 Redis Client 二方包,初始化一個(gè) Bean 實(shí)例 RedisTemplate ,一切搞定,so easy。

[[403119]]

如果是幾十、幾百并發(fā)的業(yè)務(wù)場(chǎng)景,緩存設(shè)計(jì)可能并不需要考慮那么多,但如果是億級(jí)的系統(tǒng)呢?

[[403120]]

緩存知識(shí)圖譜

首先,先了解緩存知識(shí)圖譜。

早期的緩存用于加速 CPU 數(shù)據(jù)交換的 RAM。隨著互聯(lián)網(wǎng)的快速發(fā)展,緩存的應(yīng)用更加寬泛,用于數(shù)據(jù)高速交換的存儲(chǔ)介質(zhì)都稱(chēng)之為緩存。

使用緩存時(shí),我們要關(guān)注哪些指標(biāo)?緩存有哪些應(yīng)用模式?以及緩存設(shè)計(jì)時(shí)有哪些 Tip 技巧?

一圖勝千言,如下:

 

緩存七大經(jīng)典問(wèn)題

緩存在使用過(guò)程不可避免會(huì)遇到一些問(wèn)題,對(duì)于高頻的問(wèn)題我們大概歸為了 7 類(lèi)。具體內(nèi)容下面我們一一道來(lái)。

①緩存集中失效

當(dāng)業(yè)務(wù)系統(tǒng)查詢(xún)數(shù)據(jù)時(shí),首先會(huì)查詢(xún)緩存,如果緩存中數(shù)據(jù)不存在,然后查詢(xún) DB 再將數(shù)據(jù)預(yù)熱到 Cache 中,并返回。緩存的性能比 DB 高 50~100 倍以上。

 

很多業(yè)務(wù)場(chǎng)景,如:秒殺商品、微博熱搜排行、或者一些活動(dòng)數(shù)據(jù),都是通過(guò)跑任務(wù)方式,將 DB 數(shù)據(jù)批量、集中預(yù)熱到緩存中,緩存數(shù)據(jù)有著近乎相同的過(guò)期時(shí)間。

當(dāng)過(guò)這批數(shù)據(jù)過(guò)期時(shí),會(huì)一起過(guò)期,此時(shí),對(duì)這批數(shù)據(jù)的所有請(qǐng)求,都會(huì)出現(xiàn)緩存失效,從而將壓力轉(zhuǎn)嫁到 DB,DB 的請(qǐng)求量激增,壓力變大,響應(yīng)開(kāi)始變慢。

那么有沒(méi)有解呢?當(dāng)然有了。我們可以從緩存的過(guò)期時(shí)間入口,將原來(lái)的固定過(guò)期時(shí)間,調(diào)整為過(guò)期時(shí)間=基礎(chǔ)時(shí)間+隨機(jī)時(shí)間,讓緩存慢慢過(guò)期,避免瞬間全部過(guò)期,對(duì) DB 產(chǎn)生過(guò)大壓力。

②緩存穿透

不是所有的請(qǐng)求都能查到數(shù)據(jù),不論是從緩存中還是 DB 中。

假如黑客攻擊了一個(gè)論壇,用了一堆肉雞訪(fǎng)問(wèn)一個(gè)不存的帖子 id。按照常規(guī)思路,每次都會(huì)先查緩存,緩存中沒(méi)有,接著又查 DB,同樣也沒(méi)有,此時(shí)不會(huì)預(yù)熱到 Cache 中,導(dǎo)致每次查詢(xún),都會(huì) cache miss。

由于 DB 的吞吐性能較差,會(huì)嚴(yán)重影響系統(tǒng)的性能,甚至影響正常用戶(hù)的訪(fǎng)問(wèn)。

解決方案如下:

  • 方案一:查存 DB 時(shí),如果數(shù)據(jù)不存在,預(yù)熱一個(gè)特殊空值到緩存中。這樣,后續(xù)查詢(xún)都會(huì)命中緩存,但是要對(duì)特殊值,解析處理。
  • 方案二:構(gòu)造一個(gè) BloomFilter 過(guò)濾器,初始化全量數(shù)據(jù),當(dāng)接到請(qǐng)求時(shí),在 BloomFilter 中判斷這個(gè) key 是否存在,如果不存在,直接返回即可,無(wú)需再查詢(xún)緩存和 DB。

③緩存雪崩

緩存雪崩是指部分緩存節(jié)點(diǎn)不可用,進(jìn)而導(dǎo)致整個(gè)緩存體系甚至服務(wù)系統(tǒng)不可用的情況。

分布式緩存設(shè)計(jì)一般選擇一致性 Hash,當(dāng)有部分節(jié)點(diǎn)異常時(shí),采用 rehash 策略,即把異常節(jié)點(diǎn)請(qǐng)求平均分散到其他緩存節(jié)點(diǎn)。

但是,當(dāng)較大的流量洪峰到來(lái)時(shí),如果大流量 key 比較集中,正好在某 1~2 個(gè)緩存節(jié)點(diǎn),很容易將這些緩存節(jié)點(diǎn)的內(nèi)存、網(wǎng)卡過(guò)載,緩存節(jié)點(diǎn)異常 Crash。

然后這些異常節(jié)點(diǎn)下線(xiàn),這些大流量 key 請(qǐng)求又被 rehash 到其他緩存節(jié)點(diǎn),進(jìn)而導(dǎo)致其他緩存節(jié)點(diǎn)也被過(guò)載 Crash,緩存異常持續(xù)擴(kuò)散,最終導(dǎo)致整個(gè)緩存體系異常,無(wú)法對(duì)外提供服務(wù)。

解決方案:

  • 方案一:增加實(shí)時(shí)監(jiān)控,及時(shí)預(yù)警。通過(guò)機(jī)器替換、各種故障自動(dòng)轉(zhuǎn)移策略,快速恢復(fù)緩存對(duì)外的服務(wù)能力
  • 方案二:緩存增加多個(gè)副本,當(dāng)緩存異常時(shí),再讀取其他緩存副本。為了保證副本的可用性,盡量將多個(gè)緩存副本部署在不同機(jī)架上,降低風(fēng)險(xiǎn)。

④緩存熱點(diǎn)

對(duì)于突發(fā)事件,大量用戶(hù)同時(shí)去訪(fǎng)問(wèn)熱點(diǎn)信息,這個(gè)突發(fā)熱點(diǎn)信息所在的緩存節(jié)點(diǎn)就很容易出現(xiàn)過(guò)載和卡頓現(xiàn)象,甚至 Crash,我們稱(chēng)之為緩存熱點(diǎn)。

[[403122]] 

這個(gè)在新浪微博經(jīng)常遇到,某大 V 明星出軌、結(jié)婚、離婚,瞬間引發(fā)數(shù)百千萬(wàn)的吃瓜群眾圍觀,訪(fǎng)問(wèn)同一個(gè) key,流量集中打在一個(gè)緩存節(jié)點(diǎn)機(jī)器,很容易打爆網(wǎng)卡、帶寬、CPU 的上限,最終導(dǎo)致緩存不可用。

解決方案:

  • 首先能先找到這個(gè)熱 key 來(lái),比如通過(guò) Spark 實(shí)時(shí)流分析,及時(shí)發(fā)現(xiàn)新的熱點(diǎn) key。
  • 將集中化流量打散,避免一個(gè)緩存節(jié)點(diǎn)過(guò)載。由于只有一個(gè) key,我們可以在 key 的后面拼上有序編號(hào),比如 key#01、key#02。。。key#10 多個(gè)副本,這些加工后的 key 位于多個(gè)緩存節(jié)點(diǎn)上。
  • 每次請(qǐng)求時(shí),客戶(hù)端隨機(jī)訪(fǎng)問(wèn)一個(gè)即可。

可以設(shè)計(jì)一個(gè)緩存服務(wù)治理管理后臺(tái),實(shí)時(shí)監(jiān)控緩存的 SLA,并打通分布式配置中心,對(duì)于一些 hot key 可以快速、動(dòng)態(tài)擴(kuò)容。

⑤緩存大 Key

當(dāng)訪(fǎng)問(wèn)緩存時(shí),如果 key 對(duì)應(yīng)的 value 過(guò)大,讀寫(xiě)、加載很容易超時(shí),容易引發(fā)網(wǎng)絡(luò)擁堵。

另外緩存的字段較多時(shí),每個(gè)字段的變更都會(huì)引發(fā)緩存數(shù)據(jù)的變更,頻繁的讀寫(xiě),導(dǎo)致慢查詢(xún)。

如果大 key 過(guò)期被緩存淘汰失效,預(yù)熱數(shù)據(jù)要花費(fèi)較多的時(shí)間,也會(huì)導(dǎo)致慢查詢(xún)。

所以我們?cè)谠O(shè)計(jì)緩存的時(shí)候,要注意緩存的粒度,既不能過(guò)大,如果過(guò)大很容易導(dǎo)致網(wǎng)絡(luò)擁堵;也不能過(guò)小,如果太小,查詢(xún)頻率會(huì)很高,每次請(qǐng)求都要查詢(xún)多次。

解決方案:

  • 方案一:設(shè)置一個(gè)閾值,當(dāng) value 的長(zhǎng)度超過(guò)閾值時(shí),對(duì)內(nèi)容啟動(dòng)壓縮,降低 kv 的大小。
  • 方案二:評(píng)估大 key 所占的比例,由于很多框架采用池化技術(shù),如:Memcache,可以預(yù)先分配大對(duì)象空間。真正業(yè)務(wù)請(qǐng)求時(shí),直接拿來(lái)即用。
  • 方案三:顆粒劃分,將大 key 拆分為多個(gè)小 key,獨(dú)立維護(hù),成本會(huì)降低不少。
  • 方案四:大 key 要設(shè)置合理的過(guò)期時(shí)間,盡量不淘汰那些大 key。

⑥緩存數(shù)據(jù)一致性

緩存是用來(lái)加速的,一般不會(huì)持久化儲(chǔ)存。所以,一份數(shù)據(jù)通常會(huì)存在 DB 和緩存中,由此會(huì)帶來(lái)一個(gè)問(wèn)題,如何保證這兩者的數(shù)據(jù)一致性。另外,緩存熱點(diǎn)問(wèn)題會(huì)引入多個(gè)副本備份,也可能會(huì)發(fā)生不一致現(xiàn)象。

 

解決方案:

方案一:當(dāng)緩存更新失敗后,進(jìn)行重試,如果重試失敗,將失敗的 key 寫(xiě)入 MQ 消息隊(duì)列,通過(guò)異步任務(wù)補(bǔ)償緩存,保證數(shù)據(jù)的一致性。

方案二:設(shè)置一個(gè)較短的過(guò)期時(shí)間,通過(guò)自修復(fù)的方式,在緩存過(guò)期后,緩存重新加載最新的數(shù)據(jù)。

⑦數(shù)據(jù)并發(fā)競(jìng)爭(zhēng)預(yù)熱

互聯(lián)網(wǎng)系統(tǒng)典型的特點(diǎn)就是流量大,一旦緩存中的數(shù)據(jù)過(guò)期、或因某些原因被刪除等,導(dǎo)致緩存中的數(shù)據(jù)為空,大量的并發(fā)線(xiàn)程請(qǐng)求(查詢(xún)同一個(gè) key)就會(huì)一起并發(fā)查詢(xún)數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)的壓力陡然增加。

 

如果請(qǐng)求量非常大,全部壓在數(shù)據(jù)庫(kù),可能把數(shù)據(jù)庫(kù)壓垮,進(jìn)而導(dǎo)致整個(gè)系統(tǒng)的服務(wù)不可用。

解決方案:

方案一:引入一把全局鎖,當(dāng)緩存未命中時(shí),先嘗試獲取全局鎖,如果拿到鎖,才有資格去查詢(xún) DB,并將數(shù)據(jù)預(yù)熱到緩存中。

雖然,client 端發(fā)起的請(qǐng)求非常多,但是由于拿不到鎖,只能處于等待狀態(tài),當(dāng)緩存中的數(shù)據(jù)預(yù)熱成功后,再?gòu)木彺嬷蝎@取。

 

為了便于理解,簡(jiǎn)單畫(huà)了個(gè)流程圖。這里面特別注意一個(gè)點(diǎn),由于有一個(gè)并發(fā)時(shí)間差,所以會(huì)有一個(gè)二次 check 緩存是否有值的校驗(yàn),防止緩存預(yù)熱重復(fù)覆蓋。

方案二:緩存數(shù)據(jù)創(chuàng)建多個(gè)備份,當(dāng)一個(gè)過(guò)期失效后,可以訪(fǎng)問(wèn)其他備份。

寫(xiě)在最后

緩存設(shè)計(jì)時(shí),有很多技巧,優(yōu)化手段也是千變?nèi)f化,但是我們要抓住核心要素。那就是,讓訪(fǎng)問(wèn)盡量命中緩存,同時(shí)保持?jǐn)?shù)據(jù)的一致性。

作者:TomGE

簡(jiǎn)介:前阿里架構(gòu)師,出過(guò)專(zhuān)利,競(jìng)賽拿過(guò)獎(jiǎng),,負(fù)責(zé)過(guò)電商交易、社區(qū)、營(yíng)銷(xiāo)、金融等業(yè)務(wù),多年團(tuán)隊(duì)管理經(jīng)驗(yàn)。

編輯:陶家龍

出處:轉(zhuǎn)載自公眾號(hào)微觀技術(shù)(ID:weiguanjishu)

 

責(zé)任編輯:武曉燕 來(lái)源: 微觀技術(shù)
相關(guān)推薦

2020-03-03 07:59:29

設(shè)計(jì)秒殺系統(tǒng)

2021-01-29 07:45:27

if-else代碼數(shù)據(jù)

2024-08-16 14:01:00

2020-11-10 07:12:35

Redis緩存雪崩

2019-09-18 09:41:25

億級(jí)流量網(wǎng)站

2024-10-15 16:31:30

2021-03-02 07:54:18

流量網(wǎng)關(guān)設(shè)計(jì)

2019-09-25 09:50:29

高可用微服務(wù)系統(tǒng)

2023-01-16 08:19:25

線(xiàn)上JVM調(diào)優(yōu)

2024-08-16 10:11:24

2021-08-31 07:11:48

MySQL億級(jí)流量

2021-06-25 09:55:33

Redis緩存系統(tǒng)

2019-08-01 08:36:51

緩存系統(tǒng)并發(fā)

2022-03-18 13:59:46

緩存RedisCaffeine

2020-08-20 15:55:00

MySQL數(shù)據(jù)庫(kù)使用規(guī)范

2021-12-03 10:47:28

WOT技術(shù)峰會(huì)技術(shù)

2024-11-20 19:56:36

2016-05-03 16:00:30

Web系統(tǒng)容錯(cuò)性建設(shè)

2020-09-01 07:49:14

JVM流量系統(tǒng)

2020-01-17 11:00:23

流量系統(tǒng)架構(gòu)
點(diǎn)贊
收藏

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