<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          阿里面試題:緩存的一些常見的坑,你遇到過(guò)哪些,怎么解決的?

          共 2917字,需瀏覽 6分鐘

           ·

          2021-11-10 02:58

          為什么使用緩存

          在高并發(fā)請(qǐng)求時(shí),我們會(huì)頻繁提到使用緩存技術(shù),最直接的原因是,磁盤IO及網(wǎng)絡(luò)開銷是直接請(qǐng)求內(nèi)存IO的千百上千倍;

          做個(gè)簡(jiǎn)單計(jì)算,如果我們需要某個(gè)數(shù)據(jù),該數(shù)據(jù)從數(shù)據(jù)庫(kù)磁盤讀出來(lái)需要0.0045S,經(jīng)過(guò)網(wǎng)絡(luò)請(qǐng)求傳輸需要0.0005S,那么每個(gè)請(qǐng)求完成最少需要0.005S,該數(shù)據(jù)服務(wù)器每秒最多只能響應(yīng)200個(gè)請(qǐng)求,而如果該數(shù)據(jù)存于本機(jī)內(nèi)存里,讀出來(lái)只需要100us,那么每秒能夠響應(yīng)10000個(gè)請(qǐng)求。通過(guò)將數(shù)據(jù)存儲(chǔ)到離CPU更近的未位置,減少數(shù)據(jù)傳輸時(shí)間,提高處理效率,這就是緩存的意義。

          什么場(chǎng)景下適合使用緩存

          • 讀密集型的應(yīng)用
          • 存在熱數(shù)據(jù)的應(yīng)用
          • 對(duì)響應(yīng)時(shí)效要求高的應(yīng)用
          • 對(duì)一致性要求不嚴(yán)格的場(chǎng)景
          • 需要實(shí)現(xiàn)分布式鎖的時(shí)候

          什么場(chǎng)景下不適合使用緩存

          • 對(duì)一致性要求嚴(yán)格的場(chǎng)景
          • 更新頻繁,更新數(shù)據(jù)頻率過(guò)高的場(chǎng)景,頻繁同步緩存中的數(shù)據(jù)所花費(fèi)的代價(jià)可能比不使用緩存的代價(jià)還要高
          • 讀少的場(chǎng)景,對(duì)于讀少的系統(tǒng)而言,使用緩存就完全沒有意義了,比較使用緩存是為了讀取數(shù)據(jù)更高效

          緩存收益成本對(duì)比

          收益

          1. 加速讀寫。因?yàn)榫彺嫱ǔ6际侨珒?nèi)存的系統(tǒng),通過(guò)緩存的使用可以有效提高用戶的訪問速度同時(shí)優(yōu)化用戶體驗(yàn)。

          2. 降低后端負(fù)載。通過(guò)添加緩存,如果程序沒有什么問題,在命中率還可以的情況下,可以幫助后端減少訪問量和復(fù)雜計(jì)算,很大程度降低了后端的負(fù)載。

          成本

          1. 數(shù)據(jù)不一致性。無(wú)論設(shè)計(jì)做的多么好,緩存數(shù)據(jù)與真實(shí)數(shù)據(jù)源一定存在著一定時(shí)間窗口的數(shù)據(jù)不一致性

          2. 代碼維護(hù)成本。有緩存后,代碼就會(huì)在原數(shù)據(jù)源基礎(chǔ)上加入緩存的相關(guān)代碼,例如原來(lái)只是一些sql,現(xiàn)在要加入緩存,必然增加代碼維護(hù)成本。

          3. 架構(gòu)復(fù)雜度。有緩存后,需要專門的管理人員來(lái)維護(hù)主從緩存系統(tǒng),同時(shí)也增加了架構(gòu)的復(fù)雜度和維護(hù)成本。

          高并發(fā)場(chǎng)景下帶來(lái)的常見問題

          在高并發(fā)場(chǎng)景下,緩存主要會(huì)帶來(lái)下面幾個(gè)問題:

          1.緩存一致性

          2.緩存并發(fā)(緩存擊穿)

          3.緩存穿透

          4.緩存雪崩(緩存失效)

          打個(gè)比方,你是個(gè)很有錢的人,開滿了百度云,騰訊視頻各種雜七雜八的會(huì)員,但是你就是沒有netflix的會(huì)員,然后你把這些賬號(hào)和密碼發(fā)布到一個(gè)你自己做的網(wǎng)站上,然后你有一個(gè)朋友每過(guò)十秒鐘就查詢你的網(wǎng)站,發(fā)現(xiàn)你的網(wǎng)站沒有Netflix的會(huì)員后打電話向你要。你就相當(dāng)于是個(gè)數(shù)據(jù)庫(kù),網(wǎng)站就是Redis。這就是緩存穿透。

          大家都喜歡看騰訊視頻上周星馳的《喜劇之王》,但是你的會(huì)員突然到期了,大家在你的網(wǎng)站上看不到騰訊視頻的賬號(hào),紛紛打電話向你詢問,這就是緩存擊穿

          你的各種會(huì)員突然同一時(shí)間都失效了,那這就是緩存雪崩了。

          下面一一介紹!

          緩存一致性問題

          當(dāng)數(shù)據(jù)時(shí)效性要求很高時(shí),需要保證緩存中的數(shù)據(jù)與數(shù)據(jù)庫(kù)中的保持一致,而且需要保證緩存節(jié)點(diǎn)和副本中的數(shù)據(jù)也保持一致,不能出現(xiàn)差異現(xiàn)象。這就比較依賴緩存的過(guò)期和更新策略。一般會(huì)在數(shù)據(jù)發(fā)生更改的時(shí),主動(dòng)更新緩存中的數(shù)據(jù)或者移除對(duì)應(yīng)的緩存。更多視頻教程微信搜索【碼農(nóng)編程進(jìn)階筆記

          下圖情況都會(huì)導(dǎo)致數(shù)據(jù)一致性問題

          緩存擊穿問題

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

          如圖所示:

          解決方案:

          業(yè)界比較常用的做法,是使用mutex(互斥鎖)。

          1.使用互斥鎖(mutex key)

          該方案思路比較簡(jiǎn)單,就是只讓一個(gè)線程構(gòu)建緩存,其他線程等待構(gòu)建緩存的線程執(zhí)行完,重新從緩存獲取數(shù)據(jù)就可以

          如果是單機(jī)可以用synchronized或者lock來(lái)處理,如果是分布式環(huán)境可以用分布式鎖(redis的setnx, zookeeper的添加節(jié)點(diǎn)操作)

          redis偽代碼如下:

          public?String?get(String?key)?{
          ????????String?value?=?storeClient.get(key);
          ????????StoreKey?key_mutex?=?new?MutexStoreKey(key);
          ????????if?(value?==?null)?{//代表緩存值過(guò)期
          ????????????//設(shè)置2min的超時(shí),防止刪除緩存操作失敗的時(shí)候,下次緩存過(guò)期一直不能獲取DB數(shù)據(jù)
          ????????????if?(storeClient.setnx(key_mutex,?1,?2?*?60))?{??//代表設(shè)置成功
          ????????????????value?=?db.get(key);
          ????????????????storeClient.set(key,?value,?3?*?3600);
          ????????????????storeClient.delete(key_mutex);
          ????????????}?else?{
          ????????????????sleep(1000);??//這個(gè)時(shí)候代表同時(shí)候的其他線程已經(jīng)獲取DB數(shù)據(jù)并回設(shè)到緩存了,這時(shí)候重試獲取緩存值即可
          ????????????????return?get(key);??//重試
          ????????????}
          ????????}
          ????????return?value;
          ????}

          2.“提前”使用互斥鎖(mutex key)

          即在value內(nèi)部設(shè)置1個(gè)超時(shí)值(timeout1),timeout1比實(shí)際的redis 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中。

          方案2和方案1的區(qū)別在于,如果緩存有數(shù)據(jù),但是已經(jīng)過(guò)期,會(huì)提前使用互斥鎖,查詢DB最新數(shù)據(jù)再緩存起來(lái)

          偽代碼如下,注意代碼else里面的邏輯。

          public?String?get(String?key)?{
          ????????MutexDTO?value?=?storeClient.get(key);
          ????????StoreKey?key_mutex?=?new?MutexStoreKey(key);
          ????????if?(value?==?null)?{
          ????????????if?(storeClient.setnx(key_mutex,?3?*?60?*?1000))?{
          ????????????????value?=?db.get(key);
          ????????????????storeClient.set(key,?value);
          ????????????????storeClient.delete(key_mutex);
          ????????????}?else?{
          ????????????????sleep(50);
          ????????????????get(key);
          ????????????}
          ????????}?else?{
          ????????????if?(value.getTimeout()?<=?System.currentTimeMillis())?{
          ????????????????if?(storeClient.setnx(key_mutex,?3?*?60?*?1000))?{
          ????????????????????value.setTimeout(value.getTimeout()?+?3?*?60?*?1000);
          ????????????????????storeClient.set(key,?value,?3?*?3600?*?2);

          ????????????????????value?=?db.get(key);//獲取最近DB更新數(shù)據(jù)
          ????????????????????value.setTimeout(value.getTimeout()?+?3?*?60?*?1000);
          ????????????????????storeClient.set(key,?value,?3?*?3600?*?2);
          ????????????????????storeClient.delete(key_mutex);
          ????????????????}?else?{
          ????????????????????sleep(50);
          ????????????????????get(key);
          ????????????????}
          ????????????}
          ????????}
          ?????????return?value.getValue();
          ????}

          3.緩存”永不過(guò)期“

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

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

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

          public?String?get(String?key)?{
          ????????MutexDTO?mutexDTO?=?storeClient.get(key);
          ????????String?value?=?mutexDTO.getValue();
          ????????if?(mutexDTO.getTimeout()?<=?System.currentTimeMillis())?{
          ????????????ExecutorService?singleThreadExecutor?=?Executors.newSingleThreadExecutor();//?異步更新后臺(tái)異常執(zhí)行
          ????????????singleThreadExecutor.execute(new?Runnable()?{
          ????????????????public?void?run()?{
          ????????????????????StoreKey?mutexKey?=?new?MutexStoreKey(key);
          ????????????????????if?(storeClient.setnx(mutexKey,?"1"))?{
          ????????????????????????storeClient.expire(mutexKey,?3?*?60);
          ????????????????????????String?dbValue?=?db.get(key);
          ????????????????????????storeClient.set(key,?dbValue);
          ????????????????????????storeClient.delete(mutexKey);
          ????????????????????}
          ????????????????}
          ????????????});
          ????????}
          ????????return?value;
          ????}

          三種方法如下比較:

          解決方案優(yōu)點(diǎn)缺點(diǎn)
          使用互斥鎖1.思路簡(jiǎn)單2.保證一致性1. 代碼復(fù)雜度增大2. 存在死鎖的風(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)。

          緩存穿透問題

          緩存穿透是指查詢一個(gè)一定不存在的數(shù)據(jù),由于緩存是不命中時(shí)被動(dòng)寫的,并且出于容錯(cuò)考慮,如果從存儲(chǔ)層查不到數(shù)據(jù)則不寫入緩存,這將導(dǎo)致這個(gè)不存在的數(shù)據(jù)每次請(qǐng)求都要到存儲(chǔ)層去查詢,失去了緩存的意義。

          在流量大時(shí),要是DB無(wú)法承受瞬間流量沖擊,DB可能就掛了。

          如圖所示:

          解決方案:

          有多種方法可以有效解決緩存穿透問題,一種比較簡(jiǎn)單粗暴的方法采用緩存空數(shù)據(jù),如果一個(gè)查詢返回的數(shù)據(jù)為空(數(shù)據(jù)庫(kù)中不存在該數(shù)據(jù)),仍然把這個(gè)空結(jié)果進(jìn)行緩存(過(guò)期時(shí)間一般較短)。

          另一種方法則是采用常用的布隆過(guò)濾器,將所有可能存在的數(shù)據(jù)哈希到一個(gè)足夠大的bitmap中,一個(gè)一定不存在的數(shù)據(jù)會(huì)被這個(gè)bitmap攔截掉,從而避免了對(duì)底層存儲(chǔ)系統(tǒng)的查詢壓力。

          1.緩存空數(shù)據(jù)

          當(dāng)Client請(qǐng)求MISS后,仍然將空對(duì)象保留到Cache中(可能是保留一段時(shí)間,具體問題具體分析),下次新的Request(同一個(gè)key)將會(huì)從Cache中獲取到數(shù)據(jù),保護(hù)了后端的DB。偽代碼如下:更多視頻教程微信搜索【碼農(nóng)編程進(jìn)階筆記】

          public?class?CacheNullService?{
          ????private?Cache?cache?=?new?Cache();
          ????private?Storage?storage?=?new?Storage();
          ????/**
          ?????*?模擬正常模式?
          ?????*?@param?key
          ?????*?@return
          ?????*/

          ????public?String?getNormal(String?key)?{
          ????????//?從緩存中獲取數(shù)據(jù)??
          ????????String?cacheValue?=?cache.get(key);
          ????????//?緩存為空??
          ????????if?(StringUtils.isBlank(cacheValue))?{
          ????????????//?從存儲(chǔ)中獲取??
          ????????????String?storageValue?=?storage.get(key);
          ????????????//?如果存儲(chǔ)數(shù)據(jù)不為空,將存儲(chǔ)的值設(shè)置到緩存??
          ????????????if?(StringUtils.isNotBlank(storageValue))?{
          ????????????????cache.set(key,?storageValue);
          ????????????}
          ????????????return?storageValue;
          ????????}?else?{
          ????????????//?緩存非空??
          ????????????return?cacheValue;
          ????????}
          ????}
          ????/**
          ?????*?模擬防穿透模式?
          ?????*?@param?key
          ?????*?@return
          ?????*/

          ????public?String?getPassThrough(String?key)?{
          ????????//?從緩存中獲取數(shù)據(jù)??
          ????????String?cacheValue?=?cache.get(key);
          ????????//?緩存為空??
          ????????if?(StringUtils.isBlank(cacheValue))?{
          ????????????//?從存儲(chǔ)中獲取??
          ????????????String?storageValue?=?storage.get(key);
          ????????????cache.set(key,?storageValue);
          ????????????//?如果存儲(chǔ)數(shù)據(jù)為空,需要設(shè)置一個(gè)過(guò)期時(shí)間(300秒)??
          ????????????if?(StringUtils.isBlank(storageValue))?{
          ????????????????cache.expire(key,?60?*?5);
          ????????????}
          ????????????return?storageValue;
          ????????}?else?{
          ????????????//?緩存非空??
          ????????????return?cacheValue;
          ????????}
          ????}
          }

          2.布隆過(guò)濾器

          BloomFilter 是一個(gè)非常有意思的數(shù)據(jù)結(jié)構(gòu),不僅僅可以擋住非法 key 攻擊,還可以低成本、高性能地對(duì)海量數(shù)據(jù)進(jìn)行判斷,比如一個(gè)系統(tǒng)有數(shù)億用戶和百億級(jí)新聞 feed,就可以用 BloomFilter 來(lái)判斷某個(gè)用戶是否閱讀某條新聞 feed

          在訪問所有資源(cache, DB)之前,將存在的key用布隆過(guò)濾器提前保存起來(lái),做第一層攔截。算法的簡(jiǎn)單圖解如下:

          用布隆過(guò)濾器實(shí)際只需要判斷客戶端傳過(guò)來(lái)的userCode是否存在就可以,圖中的hash1,hash2,hash3分別代表三種hash算法,不同的userCode對(duì)應(yīng)著不同的數(shù)據(jù)位,當(dāng)需要校驗(yàn)的時(shí)候,判斷每一種算法的得出來(lái)的byte位是否相同,只要一位不同,那么我們可以認(rèn)為這個(gè)userCode不存在。

          一般BloomFilter 要緩存全量的 key,這就要求全量的 key 數(shù)量不大,10 億條數(shù)據(jù)以內(nèi)最佳,因?yàn)?10 億條數(shù)據(jù)大概要占用 1.2 GB 的內(nèi)存。也可以用 BloomFilter 緩存非法 key,每次發(fā)現(xiàn)一個(gè) key 是不存在的非法 key,就記錄到 BloomFilter 中,這種記錄方案,會(huì)導(dǎo)致 BloomFilter 存儲(chǔ)的 key 持續(xù)高速增長(zhǎng),為了避免記錄 key 太多而導(dǎo)致誤判率增大,需要定期清零處理

          布隆使用案例如下:

          import?com.google.common.base.Charsets;
          import?com.google.common.hash.BloomFilter;
          import?com.google.common.hash.Funnels;

          import?java.util.*;

          public?class?BFDemo?{

          ????private?static?final?int?insertions?=?1000000;//100W

          ????public?static?void?main(String[]?args)?{
          ????????BloomFilter?bf?=?BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8),?insertions);
          ????????Set?sets?=?new?HashSet(insertions);
          ????????List?lists?=?new?ArrayList(insertions);
          ????????for?(int?i?=?0;?i?????????????String?uuid?=?UUID.randomUUID().toString();
          ????????????bf.put(uuid);
          ????????????sets.add(uuid);
          ????????????lists.add(uuid);
          ????????}
          ????????int?wrong?=?0;
          ????????int?right?=?0;
          ????????for?(int?i?=?0;?i?10000;?i++)?{
          ????????????String?test?=?i?%?100?==?0???lists.get(i?/?100)?:?UUID.randomUUID().toString();??//隨機(jī)生成1W字符串
          ????????????if?(bf.mightContain(test))?{
          ????????????????if?(sets.contains(test))?{
          ????????????????????right++;
          ????????????????}?else?{
          ????????????????????wrong++;
          ????????????????}
          ????????????}
          ????????}
          ????????System.out.println("========right======="?+?right);
          ????????System.out.println("========wrong======="?+?wrong);
          ????}

          }

          上文中提到的兩種方法,比較:

          解決方案適用場(chǎng)景優(yōu)缺點(diǎn)
          緩存空數(shù)據(jù)1. 數(shù)據(jù)命中不高2. 數(shù)據(jù)頻繁變化實(shí)時(shí)性高1.維護(hù)簡(jiǎn)單2.需要更多的緩存空間3.可能數(shù)據(jù)不一致
          布隆過(guò)濾器1. 數(shù)據(jù)命中不高2. 數(shù)據(jù)相對(duì)固定實(shí)時(shí)性低1.代碼維護(hù)復(fù)雜2.緩存空間占用少

          緩存雪崩問題

          緩存雪崩一般是由兩個(gè)原因?qū)е碌?/strong>

          第一個(gè)原因是:緩存中有大量數(shù)據(jù)同時(shí)過(guò)期,導(dǎo)致大量請(qǐng)求無(wú)法得到處理。

          如圖所示:

          解決方案:

          設(shè)計(jì)不同的過(guò)期時(shí)間

          我們可以避免給大量的數(shù)據(jù)設(shè)置相同的過(guò)期時(shí)間。如果業(yè)務(wù)層的確要求有些數(shù)據(jù)同時(shí)失效,你可以在用EXPIRE命令給每個(gè)數(shù)據(jù)設(shè)置過(guò)期時(shí)間時(shí),給這些數(shù)據(jù)的過(guò)期時(shí)間增加一個(gè)較小的隨機(jī)數(shù)(例如,隨機(jī)增加1~3分鐘),這樣一來(lái),不同數(shù)據(jù)的過(guò)期時(shí)間有所差別,但差別又不會(huì)太大,既避免了大量數(shù)據(jù)同時(shí)過(guò)期,同時(shí)也保證了這些數(shù)據(jù)基本在相近的時(shí)間失效,仍然能滿足業(yè)務(wù)需求

          服務(wù)降級(jí)處理

          發(fā)生緩存雪崩時(shí),針對(duì)不同的數(shù)據(jù)采取不同的處理方式。

          • 當(dāng)業(yè)務(wù)應(yīng)用訪問的是非核心數(shù)據(jù)時(shí),暫時(shí)停止從緩存中查詢這些數(shù)據(jù),而是直接返回預(yù)定義信息、空值或是錯(cuò)誤信息;
          • 當(dāng)業(yè)務(wù)應(yīng)用訪問的是核心數(shù)據(jù)時(shí),仍然允許查詢緩存,如果緩存缺失,也可以繼續(xù)通過(guò)數(shù)據(jù)庫(kù)讀取。

          對(duì)緩存增加多個(gè)副本

          緩存異常或請(qǐng)求 miss 后,再讀取其他緩存副本,而且多個(gè)緩存副本盡量部署在不同機(jī)架,從而確保在任何情況下,緩存系統(tǒng)都會(huì)正常對(duì)外提供服務(wù)

          對(duì)緩存體系進(jìn)行實(shí)時(shí)監(jiān)控

          當(dāng)請(qǐng)求訪問的慢速比超過(guò)閥值時(shí),及時(shí)報(bào)警,通過(guò)機(jī)器替換、服務(wù)替換進(jìn)行及時(shí)恢復(fù);也可以通過(guò)各種自動(dòng)故障轉(zhuǎn)移策略,自動(dòng)關(guān)閉異常接口、停止邊緣服務(wù)、停止部分非核心功能措施,確保在極端場(chǎng)景下,核心功能的正常運(yùn)行。

          第二個(gè)原因是:

          如果Cache層由于某些原因(宕機(jī)、cache服務(wù)掛了或者不響應(yīng)了)整體crash掉了,也就意味著所有的請(qǐng)求都會(huì)達(dá)到DB層,所有DB調(diào)用量會(huì)暴增,所以它有點(diǎn)扛不住了,甚至也會(huì)掛掉。

          如圖所示:

          雪崩過(guò)后緩存已經(jīng)crash,解決方案無(wú)非是讓DB能承受更大數(shù)據(jù)壓力,我們可以DB擴(kuò)容解決,但不是長(zhǎng)久之計(jì),最好解決辦法是如何預(yù)防緩存雪崩。

          如何預(yù)防我們可以從以下方面入手:

          保證Cache服務(wù)高可用性。

          如果我們的cache也是高可用的,即使個(gè)別實(shí)例掛掉了,影響不會(huì)很大(主從切換或者可能會(huì)有部分流量到了后端),實(shí)現(xiàn)自動(dòng)化運(yùn)維。

          例如:memcache的一致性hash、redis的sentinel和cluster機(jī)制

          依賴隔離組件為后端限流。

          其實(shí)無(wú)論是cache或者是mysql、hbase、甚至別人的RPC都會(huì)出現(xiàn)問題,我們可以將這些視同為資源,作為并發(fā)量較大的系統(tǒng),假如有一個(gè)資源不可訪問了,即使設(shè)置了超時(shí)時(shí)間,依然會(huì)hold住所有線程,造成其他資源和接口也不可以訪問。

          提前演練預(yù)估。

          在項(xiàng)目上線前,通過(guò)演練,觀察cache crash后,整體系統(tǒng)和DB的負(fù)載,提前做好預(yù)案。

          最后

          覺得有收獲,希望幫忙點(diǎn)贊,轉(zhuǎn)發(fā)下哈,謝謝,謝謝

          瀏覽 58
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色视频免费无码在线播放观看 | 台湾成人在线观看 | 中文在线字幕免费观看 | 日本黄色免费网战 | 99热在线观看精品免费 |