91在线观看视频-91在线观看视频-91在线观看免费视频-91在线观看免费-欧美第二页-欧美第1页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何設(shè)計(jì)一個(gè)緩存系統(tǒng)?

數(shù)據(jù)分析與開(kāi)發(fā) ? 來(lái)源:CSDN ? 作者:zeb_perfect ? 2021-02-08 11:40 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

設(shè)計(jì)一個(gè)緩存系統(tǒng),不得不要考慮的問(wèn)題就是:緩存穿透、緩存擊穿與失效時(shí)的雪崩效應(yīng)。

緩存穿透

緩存穿透是指查詢一個(gè)一定不存在的數(shù)據(jù),由于緩存是不命中時(shí)被動(dòng)寫(xiě)的,并且出于容錯(cuò)考慮,如果從存儲(chǔ)層查不到數(shù)據(jù)則不寫(xiě)入緩存,這將導(dǎo)致這個(gè)不存在的數(shù)據(jù)每次請(qǐng)求都要到存儲(chǔ)層去查詢,失去了緩存的意義。在流量大時(shí),可能DB就掛掉了,要是有人利用不存在的key頻繁攻擊我們的應(yīng)用,這就是漏洞。

解決方案

有很多種方法可以有效地解決緩存穿透問(wèn)題,最常見(jiàn)的則是采用布隆過(guò)濾器,將所有可能存在的數(shù)據(jù)哈希到一個(gè)足夠大的bitmap中,一個(gè)一定不存在的數(shù)據(jù)會(huì)被 這個(gè)bitmap攔截掉,從而避免了對(duì)底層存儲(chǔ)系統(tǒng)的查詢壓力。另外也有一個(gè)更為簡(jiǎn)單粗暴的方法(我們采用的就是這種),如果一個(gè)查詢返回的數(shù)據(jù)為空(不管是數(shù) 據(jù)不存在,還是系統(tǒng)故障),我們?nèi)匀话堰@個(gè)空結(jié)果進(jìn)行緩存,但它的過(guò)期時(shí)間會(huì)很短,最長(zhǎng)不超過(guò)五分鐘。

緩存雪崩

緩存雪崩是指在我們?cè)O(shè)置緩存時(shí)采用了相同的過(guò)期時(shí)間,導(dǎo)致緩存在某一時(shí)刻同時(shí)失效,請(qǐng)求全部轉(zhuǎn)發(fā)到DB,DB瞬時(shí)壓力過(guò)重雪崩。

解決方案

緩存失效時(shí)的雪崩效應(yīng)對(duì)底層系統(tǒng)的沖擊非常可怕。大多數(shù)系統(tǒng)設(shè)計(jì)者考慮用加鎖或者隊(duì)列的方式保證緩存的單線 程(進(jìn)程)寫(xiě),從而避免失效時(shí)大量的并發(fā)請(qǐng)求落到底層存儲(chǔ)系統(tǒng)上。這里分享一個(gè)簡(jiǎn)單方案就時(shí)講緩存失效時(shí)間分散開(kāi),比如我們可以在原有的失效時(shí)間基礎(chǔ)上增加一個(gè)隨機(jī)值,比如1-5分鐘隨機(jī),這樣每一個(gè)緩存的過(guò)期時(shí)間的重復(fù)率就會(huì)降低,就很難引發(fā)集體失效的事件。

緩存擊穿

對(duì)于一些設(shè)置了過(guò)期時(shí)間的key,如果這些key可能會(huì)在某些時(shí)間點(diǎn)被超高并發(fā)地訪問(wèn),是一種非常“熱點(diǎn)”的數(shù)據(jù)。這個(gè)時(shí)候,需要考慮一個(gè)問(wèn)題:緩存被“擊穿”的問(wèn)題,這個(gè)和緩存雪崩的區(qū)別在于這里針對(duì)某一key緩存,前者則是很多key。

緩存在某個(gè)時(shí)間點(diǎn)過(guò)期的時(shí)候,恰好在這個(gè)時(shí)間點(diǎn)對(duì)這個(gè)Key有大量的并發(fā)請(qǐng)求過(guò)來(lái),這些請(qǐng)求發(fā)現(xiàn)緩存過(guò)期一般都會(huì)從后端DB加載數(shù)據(jù)并回設(shè)到緩存,這個(gè)時(shí)候大并發(fā)的請(qǐng)求可能會(huì)瞬間把后端DB壓垮。

解決方案

1.使用互斥鎖(mutex key)

業(yè)界比較常用的做法,是使用mutex。簡(jiǎn)單地來(lái)說(shuō),就是在緩存失效的時(shí)候(判斷拿出來(lái)的值為空),不是立即去load db,而是先使用緩存工具的某些帶成功操作返回值的操作(比如Redis的SETNX或者M(jìn)emcache的ADD)去set一個(gè)mutex key,當(dāng)操作返回成功時(shí),再進(jìn)行l(wèi)oad db的操作并回設(shè)緩存;否則,就重試整個(gè)get緩存的方法。

SETNX,是「SET if Not eXists」的縮寫(xiě),也就是只有不存在的時(shí)候才設(shè)置,可以利用它來(lái)實(shí)現(xiàn)鎖的效果。在redis2.6.1之前版本未實(shí)現(xiàn)setnx的過(guò)期時(shí)間,所以這里給出兩種版本代碼參考:

//2.6.1前單機(jī)版本鎖 Stringget(Stringkey){ Stringvalue=redis.get(key); if(value==null){ if(redis.setnx(key_mutex,"1")){ //3mintimeouttoavoidmutexholdercrash redis.expire(key_mutex,3*60) value=db.get(key); redis.set(key,value); redis.delete(key_mutex); }else{ //其他線程休息50毫秒后重試 Thread.sleep(50); get(key); } } }

最新版本代碼:

publicStringget(key){ Stringvalue=redis.get(key); if(value==null){//代表緩存值過(guò)期 //設(shè)置3min的超時(shí),防止del操作失敗的時(shí)候,下次緩存過(guò)期一直不能loaddb if(redis.setnx(key_mutex,1,3*60)==1){//代表設(shè)置成功 value=db.get(key); redis.set(key,value,expire_secs); redis.del(key_mutex); }else{//這個(gè)時(shí)候代表同時(shí)候的其他線程已經(jīng)loaddb并回設(shè)到緩存了,這時(shí)候重試獲取緩存值即可 sleep(50); get(key);//重試 } }else{ returnvalue; } }

memcache代碼:

if(memcache.get(key)==null){ //3mintimeouttoavoidmutexholdercrash if(memcache.add(key_mutex,3*60*1000)==true){ value=db.get(key); memcache.set(key,value); memcache.delete(key_mutex); }else{ sleep(50); retry(); } }

2. "提前"使用互斥鎖(mutex key):

在value內(nèi)部設(shè)置1個(gè)超時(shí)值(timeout1), timeout1比實(shí)際的memcache timeout(timeout2)小。當(dāng)從cache讀取到timeout1發(fā)現(xiàn)它已經(jīng)過(guò)期時(shí)候,馬上延長(zhǎng)timeout1并重新設(shè)置到cache。然后再?gòu)臄?shù)據(jù)庫(kù)加載數(shù)據(jù)并設(shè)置到cache中。偽代碼如下:

v=memcache.get(key); if(v==null){ if(memcache.add(key_mutex,3*60*1000)==true){ value=db.get(key); memcache.set(key,value); memcache.delete(key_mutex); }else{ sleep(50); retry(); } }else{ if(v.timeout<=?now())?{?? ????????if?(memcache.add(key_mutex,?3?*?60?*?1000)?==?true)?{?? ????????????//?extend?the?timeout?for?other?threads?? ????????????v.timeout?+=?3?*?60?*?1000;?? ????????????memcache.set(key,?v,?KEY_TIMEOUT?*?2);?? ?? ????????????//?load?the?latest?value?from?db?? ????????????v?=?db.get(key);?? ????????????v.timeout?=?KEY_TIMEOUT;?? ????????????memcache.set(key,?value,?KEY_TIMEOUT?*?2);?? ????????????memcache.delete(key_mutex);?? ????????}?else?{?? ????????????sleep(50);?? ????????????retry();?? ????????}?? ????}?? }?

3. "永遠(yuǎn)不過(guò)期":

這里的“永遠(yuǎn)不過(guò)期”包含兩層意思:

(1) 從redis上看,確實(shí)沒(méi)有設(shè)置過(guò)期時(shí)間,這就保證了,不會(huì)出現(xiàn)熱點(diǎn)key過(guò)期問(wèn)題,也就是“物理”不過(guò)期。

(2) 從功能上看,如果不過(guò)期,那不就成靜態(tài)的了嗎?所以我們把過(guò)期時(shí)間存在key對(duì)應(yīng)的value里,如果發(fā)現(xiàn)要過(guò)期了,通過(guò)一個(gè)后臺(tái)的異步線程進(jìn)行緩存的構(gòu)建,也就是“邏輯”過(guò)期

從實(shí)戰(zhàn)看,這種方法對(duì)于性能非常友好,唯一不足的就是構(gòu)建緩存時(shí)候,其余線程(非構(gòu)建緩存的線程)可能訪問(wèn)的是老數(shù)據(jù),但是對(duì)于一般的互聯(lián)網(wǎng)功能來(lái)說(shuō)這個(gè)還是可以忍受。

Stringget(finalStringkey){ Vv=redis.get(key); Stringvalue=v.getValue(); longtimeout=v.getTimeout(); if(v.timeout<=?System.currentTimeMillis())?{?? ????????????//?異步更新后臺(tái)異常執(zhí)行?? ????????????threadPool.execute(new?Runnable()?{?? ????????????????public?void?run()?{?? ????????????????????String?keyMutex?=?"mutex:"?+?key;?? ????????????????????if?(redis.setnx(keyMutex,?"1"))?{?? ????????????????????????//?3?min?timeout?to?avoid?mutex?holder?crash?? ????????????????????????redis.expire(keyMutex,?3?*?60);?? ????????????????????????String?dbValue?=?db.get(key);?? ????????????????????????redis.set(key,?dbValue);?? ????????????????????????redis.delete(keyMutex);?? ????????????????????}?? ????????????????}?? ????????????});?? ????????}?? ????????return?value;?? }

4. 資源保護(hù):

采用netflix的hystrix,可以做資源的隔離保護(hù)主線程池,如果把這個(gè)應(yīng)用到緩存的構(gòu)建也未嘗不可。

沒(méi)有最佳只有最合適

解決方案 優(yōu)點(diǎn) 缺點(diǎn)
簡(jiǎn)單分布式互斥鎖(mutex key) 1. 思路簡(jiǎn)單
2. 保證一致性
1. 代碼復(fù)雜度增大
2. 存在死鎖的風(fēng)險(xiǎn)
3. 存在線程池阻塞的風(fēng)險(xiǎn)
“提前”使用互斥鎖 1. 保證一致性 同上
不過(guò)期(本文) 1. 異步構(gòu)建緩存,不會(huì)阻塞線程池 1. 不保證一致性。
2. 代碼復(fù)雜度增大(每個(gè)value都要維護(hù)一個(gè)timekey)。
3. 占用一定的內(nèi)存空間(每個(gè)value都要維護(hù)一個(gè)timekey)。
資源隔離組件hystrix(本文) 1. hystrix技術(shù)成熟,有效保證后端。
2. hystrix監(jiān)控強(qiáng)大。
1. 部分訪問(wèn)存在降級(jí)策略。

四種方案來(lái)源網(wǎng)絡(luò),詳文鏈接:http://carlosfu.iteye.com/blog/2269687

總結(jié)

針對(duì)業(yè)務(wù)系統(tǒng),永遠(yuǎn)都是具體情況具體分析,沒(méi)有最好,只有最合適。

最后,對(duì)于緩存系統(tǒng)常見(jiàn)的緩存滿了和數(shù)據(jù)丟失問(wèn)題,需要根據(jù)具體業(yè)務(wù)分析,通常我們采用LRU策略處理溢出,Redis的RDB和AOF持久化策略來(lái)保證一定情況下的數(shù)據(jù)安全。

原文標(biāo)題:如何設(shè)計(jì)緩存系統(tǒng):緩存穿透,緩存擊穿,緩存雪崩解決方案分析

文章出處:【微信公眾號(hào):數(shù)據(jù)分析與開(kāi)發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

責(zé)任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 存儲(chǔ)
    +關(guān)注

    關(guān)注

    13

    文章

    4535

    瀏覽量

    87490
  • 緩存
    +關(guān)注

    關(guān)注

    1

    文章

    246

    瀏覽量

    27202

原文標(biāo)題:如何設(shè)計(jì)緩存系統(tǒng):緩存穿透,緩存擊穿,緩存雪崩解決方案分析

文章出處:【微信號(hào):DBDevs,微信公眾號(hào):數(shù)據(jù)分析與開(kāi)發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    高性能緩存設(shè)計(jì):如何解決緩存偽共享問(wèn)題

    在多核高并發(fā)場(chǎng)景下, 緩存偽共享(False Sharing) 是導(dǎo)致性能驟降的“隱形殺手”。當(dāng)不同線程頻繁修改同緩存行(Cache Line)中的獨(dú)立變量時(shí),CPU緩存
    的頭像 發(fā)表于 07-01 15:01 ?132次閱讀
    高性能<b class='flag-5'>緩存</b>設(shè)計(jì):如何解決<b class='flag-5'>緩存</b>偽共享問(wèn)題

    MCU緩存設(shè)計(jì)

    MCU 設(shè)計(jì)通過(guò)優(yōu)化指令與數(shù)據(jù)的訪問(wèn)效率,顯著提升系統(tǒng)性能并降低功耗,其核心架構(gòu)與實(shí)現(xiàn)策略如下: 緩存類型與結(jié)構(gòu) 指令緩存(I-Cache)與數(shù)據(jù)
    的頭像 發(fā)表于 05-07 15:29 ?360次閱讀

    Nginx緩存配置詳解

    Nginx 是個(gè)功能強(qiáng)大的 Web 服務(wù)器和反向代理服務(wù)器,它可以用于實(shí)現(xiàn)靜態(tài)內(nèi)容的緩存緩存可以分為客戶端緩存和服務(wù)端
    的頭像 發(fā)表于 05-07 14:03 ?600次閱讀
    Nginx<b class='flag-5'>緩存</b>配置詳解

    nginx中強(qiáng)緩存和協(xié)商緩存介紹

    強(qiáng)緩存直接告訴瀏覽器:在緩存過(guò)期前,無(wú)需與服務(wù)器通信,直接使用本地緩存
    的頭像 發(fā)表于 04-01 16:01 ?388次閱讀

    緩存與不帶緩存的固態(tài)硬盤有什么區(qū)別

    隨著信息技術(shù)的不斷進(jìn)步,存儲(chǔ)設(shè)備作為計(jì)算機(jī)系統(tǒng)的核心組成部分,其性能與穩(wěn)定性直接影響到整個(gè)系統(tǒng)的運(yùn)行效率。固態(tài)硬盤(Solid State Disk,簡(jiǎn)稱SSD)作為新代存儲(chǔ)設(shè)備,以其高速讀寫(xiě)、低
    的頭像 發(fā)表于 02-06 16:35 ?2403次閱讀

    基于javaPoet的緩存key優(yōu)化實(shí)踐

    作者:京東物流 方志民 . 背景 在系統(tǒng)opsreview中,發(fā)現(xiàn)了些服務(wù)配置了@Cacheable注解。@cacheable 來(lái)源于spring cache框架中,作用是使用
    的頭像 發(fā)表于 01-14 15:18 ?830次閱讀
    基于javaPoet的<b class='flag-5'>緩存</b>key優(yōu)化實(shí)踐

    緩存對(duì)大數(shù)據(jù)處理的影響分析

    緩存對(duì)大數(shù)據(jù)處理的影響顯著且重要,主要體現(xiàn)在以下幾個(gè)方面: 、提高數(shù)據(jù)訪問(wèn)速度 在大數(shù)據(jù)環(huán)境中,數(shù)據(jù)存儲(chǔ)通常采用分布式存儲(chǔ)系統(tǒng),數(shù)據(jù)量龐大,直接從存儲(chǔ)系統(tǒng)中讀取數(shù)據(jù)會(huì)存在較高的延遲。
    的頭像 發(fā)表于 12-18 09:45 ?779次閱讀

    HTTP緩存頭的使用 本地緩存與遠(yuǎn)程緩存的區(qū)別

    HTTP緩存頭是組HTTP響應(yīng)頭,它們控制瀏覽器和中間代理服務(wù)器如何緩存網(wǎng)頁(yè)內(nèi)容。合理使用HTTP緩存頭可以顯著提高網(wǎng)站的加載速度和性能,減少服務(wù)器的負(fù)載。 1. HTTP
    的頭像 發(fā)表于 12-18 09:41 ?473次閱讀

    Web緩存的類型及功能分析

    速度,降低了延遲,并提高了網(wǎng)站的可用性。 Web緩存的類型 Web緩存主要分為以下幾種類型: 瀏覽器緩存(Browser Cache) 功能 :瀏覽器緩存是用戶計(jì)算機(jī)上的
    的頭像 發(fā)表于 12-18 09:35 ?788次閱讀

    緩存技術(shù)在軟件開(kāi)發(fā)中的應(yīng)用

    在現(xiàn)代軟件開(kāi)發(fā)中,隨著數(shù)據(jù)量的爆炸性增長(zhǎng)和用戶對(duì)響應(yīng)速度的高要求,緩存技術(shù)成為了提升系統(tǒng)性能的重要手段。緩存技術(shù)通過(guò)將數(shù)據(jù)存儲(chǔ)在離用戶更近的位置,減少數(shù)據(jù)訪問(wèn)延遲,提高數(shù)據(jù)處理速度,從而優(yōu)化
    的頭像 發(fā)表于 12-18 09:32 ?723次閱讀

    什么是緩存(Cache)及其作用

    緩存(Cache)是種高速存儲(chǔ)器,用于臨時(shí)存儲(chǔ)數(shù)據(jù),以便快速訪問(wèn)。在計(jì)算機(jī)系統(tǒng)中,緩存的作用是減少處理器訪問(wèn)主存儲(chǔ)器(如隨機(jī)存取存儲(chǔ)器RAM)所需的時(shí)間。
    的頭像 發(fā)表于 12-18 09:28 ?1.2w次閱讀

    探討移動(dòng)設(shè)備中的緩存文件管理

    ? 本文發(fā)表于FAST 2022。 探討 緩存文件管理方法。本文 通過(guò)個(gè)輕量級(jí)的基于機(jī)器學(xué)習(xí)的分類引擎來(lái)篩選和個(gè)性化管理緩存文件 ,實(shí)驗(yàn) 在 華為P9 和 Mate30 兩部手機(jī)上進(jìn)
    的頭像 發(fā)表于 11-28 11:50 ?1080次閱讀
    探討移動(dòng)設(shè)備中的<b class='flag-5'>緩存</b>文件管理

    緩存之美——如何選擇合適的本地緩存

    Guava cache是Google開(kāi)發(fā)的Guava工具包中套完善的JVM本地緩存框架,底層實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu)類似于ConcurrentHashMap,但是進(jìn)行了更多的能力拓展,包括緩存過(guò)期時(shí)間設(shè)置、
    的頭像 發(fā)表于 11-17 14:24 ?823次閱讀
    <b class='flag-5'>緩存</b>之美——如何選擇合適的本地<b class='flag-5'>緩存</b>?

    異構(gòu)計(jì)算下緩存致性的重要性

    在眾多回復(fù)中,李博杰同學(xué)的回答被認(rèn)為質(zhì)量最高。他首先將緩存致性分為兩個(gè)主要場(chǎng)景:是主機(jī)內(nèi)CPU與設(shè)備間的致性;二是跨主機(jī)的
    的頭像 發(fā)表于 10-24 17:00 ?1731次閱讀
    異構(gòu)計(jì)算下<b class='flag-5'>緩存</b><b class='flag-5'>一</b>致性的重要性

    什么是CPU緩存?它有哪些作用?

    CPU緩存(Cache Memory)是計(jì)算機(jī)系統(tǒng)個(gè)至關(guān)重要的組成部分,它位于CPU與內(nèi)存之間,作為兩者之間的臨時(shí)存儲(chǔ)器。CPU緩存的主
    的頭像 發(fā)表于 08-22 14:54 ?6189次閱讀
    主站蜘蛛池模板: 曰韩毛片| 亚洲经典乱码在线播 | 欧美久久天天综合香蕉伊 | 亚洲狠狠操 | 台湾av | 噜噜噜色噜噜噜久久 | 99国产精品农村一级毛片 | 韩国三级无遮挡床戏视频 | 国产尤物在线视频 | 视频免费观看网址 | 国产精品久久久精品三级 | 大色综合| 亚洲日本欧美 | 美女张开腿让男人桶爽 | 日本免费xxxx色视频 | 色5566| 欧美亚洲天堂 | 成人在线免费网站 | 国产高清在线观看 | 麻豆国产一区二区在线观看 | 国产清纯白嫩大学生正在播放 | 四虎影院在线网址 | 狠狠干精品 | 久久婷婷久久一区二区三区 | 色视频免费看 | 日本久久久久久久 | 九九热国产| 四虎影视在线看 | 男人午夜禁片在线观看 | 18毛片 | 亚洲大色 | 欧美成人xxxx | 男女爱爱爽爽福利免费视频 | 性做久久久久久久 | 亚洲欧美在线播放 | 天天看影院 | 天天爽夜夜爽天天做夜夜做 | 免费jyzzjyzz在线播放大全 | 欧美三级一区二区三区 | 欧美一区二区三区免费看 | 闲人综合 |