解鎖緩存的正確姿勢(shì)

[TOC]

[圖片上傳失敗...(image-2e0e27-1615694322860)]

常見(jiàn)概念:

  • cache miss:表示沒(méi)有命中緩存阐枣,如果緩存內(nèi)容中還有內(nèi)存空間的話涛漂,會(huì)將數(shù)據(jù)加入緩存中。
  • 存儲(chǔ)成本:當(dāng)沒(méi)有命中緩存時(shí)伦仍,回源獲取會(huì)將數(shù)據(jù)防止到存儲(chǔ)中结窘,整個(gè)數(shù)據(jù)放置到存儲(chǔ)空間所需要的時(shí)間以及空間稱之為存儲(chǔ)成本。

訪問(wèn)緩存場(chǎng)景分析:

緩存穿透

現(xiàn)象:每次請(qǐng)求直接穿透緩存層充蓝,直接回源到數(shù)據(jù)庫(kù)中,給數(shù)據(jù)庫(kù)帶來(lái)了巨大訪問(wèn)壓力,甚至宕機(jī)谓苟。

原因:訪問(wèn)數(shù)據(jù)會(huì)先訪問(wèn)緩存官脓,如果緩存中數(shù)據(jù)不存在緩存中才會(huì)查詢數(shù)據(jù)庫(kù),但是如果查詢數(shù)據(jù)庫(kù)也查詢不出來(lái)數(shù)據(jù)涝焙,也是說(shuō)當(dāng)前訪問(wèn)數(shù)據(jù)永遠(yuǎn)不會(huì)寫入緩存中卑笨。這就導(dǎo)致了,訪問(wèn)一定不存在的數(shù)據(jù)仑撞,就相當(dāng)于緩存形同虛設(shè)赤兴,每次請(qǐng)求都會(huì)到db層,造成數(shù)據(jù)庫(kù)負(fù)擔(dān)過(guò)大隧哮。
解決方案:

  1. 如果db查詢不到數(shù)據(jù)桶良,保存空對(duì)象到緩存層,設(shè)置較短的失效時(shí)間
  2. 采用bloom filter保存緩存過(guò)的key沮翔,在訪問(wèn)請(qǐng)求到來(lái)時(shí)可以過(guò)濾掉不存在的key陨帆,防止這些請(qǐng)求到db層。(相當(dāng)于保存了一份歷史采蚀,如果歷史中沒(méi)有的疲牵,不讓請(qǐng)求到db層)
  3. 針對(duì)業(yè)務(wù)場(chǎng)景對(duì)請(qǐng)求的參數(shù)進(jìn)行有效性校驗(yàn),防止非法請(qǐng)求擊垮db

緩存擊穿

現(xiàn)象:當(dāng)某一key失效時(shí)榆鼠,造成大量請(qǐng)求到db層纲爸,擊垮存儲(chǔ)層。

原因:為了保證緩存數(shù)據(jù)的時(shí)效性妆够,通常會(huì)設(shè)置一個(gè)失效時(shí)間识啦,如果是熱點(diǎn)key,高并發(fā)時(shí)會(huì)有海量請(qǐng)求直接越過(guò)緩存層到數(shù)據(jù)庫(kù)责静,這樣就會(huì)給數(shù)據(jù)庫(kù)造成的負(fù)擔(dān)增大袁滥,甚至宕機(jī)。

解決方案:

  1. 使用互斥鎖灾螃,當(dāng)緩存失效時(shí)题翻,保證一個(gè)請(qǐng)求能訪問(wèn)數(shù)據(jù)庫(kù),并更新緩存腰鬼,其他線程等待并重試嵌赠。
  2. 緩存數(shù)據(jù)“永不過(guò)期”:如果緩存數(shù)據(jù)不設(shè)置失效時(shí)間的話,就不會(huì)存在熱點(diǎn)key過(guò)期造成了大量請(qǐng)求到數(shù)據(jù)庫(kù)熄赡。但是姜挺,緩存數(shù)據(jù)就變成“靜態(tài)數(shù)據(jù)”,因此當(dāng)緩存數(shù)據(jù)快要過(guò)期時(shí)彼硫,采用異步線程的方式提前進(jìn)行更新緩存數(shù)據(jù)炊豪。(后臺(tái)偷偷更新)

緩存雪崩

現(xiàn)象:多個(gè)key失效凌箕,造成大量請(qǐng)求到db層,導(dǎo)致db層負(fù)擔(dān)過(guò)重甚至宕機(jī)

原因:緩存雪崩是指在我們?cè)O(shè)置緩存時(shí)采用了相同的過(guò)期時(shí)間词渤,導(dǎo)致緩存在某一時(shí)刻同時(shí)失效牵舱,請(qǐng)求全部轉(zhuǎn)發(fā)到數(shù)據(jù)庫(kù),最終導(dǎo)致數(shù)據(jù)庫(kù)瞬時(shí)壓力過(guò)大而崩潰缺虐。

解決方案:

  1. 方案一:使用互斥鎖的方式芜壁,保證只有單個(gè)線程進(jìn)行請(qǐng)求能夠到達(dá)db層。
  2. 方案二:在每個(gè)key的失效時(shí)間的基礎(chǔ)上再加一個(gè)1到5分鐘的隨機(jī)值高氮,這樣就能保證大規(guī)模key集體失效的概率慧妄,并且需要讓多個(gè)key的失效時(shí)間能夠均勻分布。

緩存擊穿強(qiáng)調(diào)的是熱點(diǎn)key的失效剪芍,導(dǎo)致某一時(shí)刻大量請(qǐng)求會(huì)直接到db層塞淹,解決方案的核心原則是規(guī)避數(shù)據(jù)庫(kù)的并發(fā)操作。緩存雪崩強(qiáng)調(diào)的多個(gè)key的集體失效紊浩,與key是否是熱點(diǎn)數(shù)據(jù)并不是必然的因素窖铡,解決方案的核心原則則讓key之間的失效時(shí)間分布更加均勻,避免集體失效的情況坊谁。

數(shù)據(jù)更新場(chǎng)景分析

為什么不是更新緩存费彼,而是失效(刪除)緩存?

  1. 并發(fā)寫容易寫覆蓋造成臟數(shù)據(jù)的問(wèn)題(具體情況參考文章)
  2. 雙寫不同數(shù)據(jù)源容易造成數(shù)據(jù)不一致
  3. 違背數(shù)據(jù)懶加載口芍,避免不必要的計(jì)算消耗(如果有些緩存值是需要經(jīng)過(guò)復(fù)雜的計(jì)算才能得出箍铲,所以如果每次更新數(shù)據(jù)的時(shí)候都更新緩存,但是后續(xù)在一段時(shí)間內(nèi)并沒(méi)有讀取該緩存數(shù)據(jù)鬓椭,這樣就白白浪費(fèi)了大量的計(jì)算性能颠猴,完全可以后續(xù)由讀請(qǐng)求的時(shí)候,再去計(jì)算即可小染,這樣更符合數(shù)據(jù)懶加載翘瓮,降低計(jì)算開(kāi)銷。)

可能存在的更新時(shí)序裤翩?

  1. 先緩存失效再更新數(shù)據(jù)庫(kù)
    [圖片上傳失敗...(image-49d50f-1615694322860)]
  2. 假設(shè)在并發(fā)的情況下资盅,按照這種更新時(shí)序會(huì)存在什么問(wèn)題?
    線程A先失效緩存數(shù)據(jù)的時(shí)候踊赠,B線程讀請(qǐng)求發(fā)現(xiàn)緩存數(shù)據(jù)為空的話呵扛,就會(huì)從數(shù)據(jù)庫(kù)中讀取舊值放入到緩存中,這樣就導(dǎo)致后續(xù)的讀請(qǐng)求讀到的都是緩存中的臟數(shù)據(jù)筐带。針對(duì)這樣的情況可以采用延時(shí)雙刪的策略來(lái)有效避免今穿,偽代碼 如下:
cache.delKey(key); 
db.update(data);
Thread.sleep(xxx); 
cache.delKey(key);

主要是在寫請(qǐng)求更新完數(shù)據(jù)庫(kù)后進(jìn)行休眠一段時(shí)間,然后刪除可能由讀請(qǐng)求帶來(lái)的臟數(shù)據(jù)存入到緩存伦籍。另外蓝晒,數(shù)據(jù)庫(kù)如果采用的是主從分離的架構(gòu)的話腮出,讀出來(lái)的數(shù)據(jù)也有可能是主從未同步完成造成的臟數(shù)據(jù)。這種通過(guò)延時(shí)雙刪的方式需要線程休眠拔创,因此很顯然會(huì)降低系統(tǒng)吞吐量利诺,并不是一種優(yōu)雅的解決方式富蓄,也可以采用異步刪除的方式剩燥。當(dāng)然可以設(shè)置過(guò)期時(shí)間,到期后緩存失效載入最新的數(shù)據(jù)立倍,需要系統(tǒng)能夠容忍一段時(shí)間的數(shù)據(jù)不一致灭红。

  1. 先更新數(shù)據(jù)再失效緩存:這是推薦的更新數(shù)據(jù)時(shí)采用的方式,實(shí)際上這也是可能存在數(shù)據(jù)不一致的情況:
    [圖片上傳失敗...(image-4e5d0e-1615694322860)]
    假設(shè)緩存剛好到期失效時(shí)口注,讀請(qǐng)求從db中讀取數(shù)據(jù)变擒,寫請(qǐng)求更新完數(shù)據(jù)后再失效緩存后,讀請(qǐng)求將舊數(shù)據(jù)存入到緩存中寝志,這種情況也會(huì)導(dǎo)致臟數(shù)據(jù)的問(wèn)題娇斑。實(shí)際上這種情況發(fā)生的概率很低,要發(fā)生這種情況的前提條件是寫數(shù)據(jù)庫(kù)要先于讀數(shù)據(jù)庫(kù)完成材部,一般而言讀數(shù)據(jù)庫(kù)相比于寫數(shù)據(jù)庫(kù)要耗時(shí)更短毫缆,這種前提條件成立的概率很低。針對(duì)這種”邏輯失敗“造成的數(shù)據(jù)不一致乐导,可以采用上面所說(shuō)的異步雙刪的策略以及過(guò)期失效的方式來(lái)避免苦丁。
    個(gè)人理解:緩存剛好到期,此時(shí)讀請(qǐng)求到db來(lái)讀取緩存物臂,讀和寫數(shù)據(jù)庫(kù)發(fā)生并發(fā)旺拉,寫數(shù)據(jù)庫(kù)先完成,刪除了緩存棵磷,然后讀請(qǐng)求是拿到的老數(shù)據(jù)蛾狗,導(dǎo)致緩存在被刪除后,又更新為了讀到的老數(shù)據(jù)仪媒。

Write/Read Through

Cache Aside Pattern對(duì)db以及緩存的更新邏輯是由調(diào)用方自己去控制沉桌,很顯然這是一個(gè)很復(fù)雜的過(guò)程。Write/Read Through對(duì)調(diào)用方而言规丽,緩存是作為整個(gè)的數(shù)據(jù)存儲(chǔ)蒲牧,而不用關(guān)系緩存后面的db赌莺,數(shù)據(jù)庫(kù)的更新則是由緩存統(tǒng)一進(jìn)行管理,對(duì)調(diào)用方而言只需要和緩存進(jìn)行交互艘狭,整體過(guò)程是透明的翠订。

  • Read Through:當(dāng)數(shù)據(jù)發(fā)生更新時(shí),查詢緩存時(shí)更新緩存遵倦,然后由緩存層同步的更新數(shù)據(jù)庫(kù)即可,對(duì)調(diào)用方而言只需要和緩存層交互即可似谁;
  • Write Through:Write Through 套路和Read Through相仿,不過(guò)是在更新數(shù)據(jù)時(shí)發(fā)生掠哥。當(dāng)有數(shù)據(jù)更新的時(shí)候巩踏,如果沒(méi)有命中緩存,直接更新數(shù)據(jù)庫(kù)塞琼,然后返回禁舷。如果命中了緩存,則更新緩存派近,然后再由Cache自己同步更新數(shù)據(jù)庫(kù)霜大。如下圖所示(來(lái)源于網(wǎng)絡(luò)):

[圖片上傳失敗...(image-5ba324-1615694322860)]

Write Behind Cache Pattern

這種模式是當(dāng)數(shù)據(jù)更新的時(shí)候直接更新緩存數(shù)據(jù),然后建立異步任務(wù)去更新數(shù)據(jù)庫(kù)战坤。這種異步方式請(qǐng)求響應(yīng)會(huì)很快途茫,系統(tǒng)的吞吐量會(huì)明顯提升。但是囊卜,因?yàn)槭钱惒礁聰?shù)據(jù)庫(kù)栅组,數(shù)據(jù)一致性的保障就會(huì)變?nèi)酰绻聰?shù)據(jù)庫(kù)失敗則會(huì)永遠(yuǎn)的造成系統(tǒng)臟數(shù)據(jù)刃麸,需要很精細(xì)設(shè)計(jì)系統(tǒng)重試的策略司浪,另外如果異步服務(wù)宕機(jī)的話把沼,還要考慮更新的數(shù)據(jù)如何持久化,服務(wù)重啟后能夠迅速恢復(fù)饮睬。在更新數(shù)據(jù)庫(kù)時(shí)篮奄,由于并發(fā)多任務(wù)的存在,還需要考慮并發(fā)寫是否會(huì)造成臟數(shù)據(jù)的問(wèn)題牙瓢,就需要追溯每次更新數(shù)據(jù)的時(shí)序间校。使用這種模式需要考慮的細(xì)節(jié)會(huì)有很多页慷,設(shè)計(jì)出一套好的方案是件很不容易的事情酒繁。

數(shù)據(jù)不一致問(wèn)題

原因:

邏輯失敗造成的數(shù)據(jù)不一致: 在上一章主要分析了更新數(shù)據(jù)時(shí)的四種更新策略,在并發(fā)的情況下揭绑,無(wú)論是先刪除緩存還是更新數(shù)據(jù)庫(kù)郎哭,還是更新數(shù)據(jù)庫(kù)再失效緩存,都會(huì)數(shù)據(jù)不一致的情況邦蜜,主要是因?yàn)楫惒阶x寫請(qǐng)求在并發(fā)情況下的操作時(shí)序?qū)е碌臄?shù)據(jù)不一致亥至,稱之為”邏輯失敗“姐扮。解決這種因?yàn)椴l(fā)時(shí)序?qū)е碌膯?wèn)題,核心的解決思想是將異步操作進(jìn)行串行化

物理失敗造成的數(shù)據(jù)不一致: 在cache aside pattern中先更新數(shù)據(jù)庫(kù)再刪除緩存以及異步雙刪策略等等壤靶,如果刪除緩存失敗時(shí)都出現(xiàn)數(shù)據(jù)不一致的情況睡榆。但是數(shù)據(jù)庫(kù)更新以及緩存操作是沒(méi)辦法放到一個(gè)事務(wù)中袍榆,一般來(lái)說(shuō)塘揣,使用緩存是分布式緩存如果緩存服務(wù)很耗時(shí)亲铡,那么將更新數(shù)據(jù)庫(kù)以及失效緩存放到一個(gè)事務(wù)中,就會(huì)造成大量的數(shù)據(jù)庫(kù)連接掛起赞草,嚴(yán)重的降低系統(tǒng)性能吆鹤,甚至?xí)驗(yàn)閿?shù)據(jù)庫(kù)連接數(shù)過(guò)多,導(dǎo)致系統(tǒng)崩潰沾凄。像這種因?yàn)榫彺娌僮魇≈剩瑢?dǎo)致的數(shù)據(jù)不一致稱之為”物理失敗“温鸽。大多數(shù)情況物理失敗的情況會(huì)重用重試的方式進(jìn)行解決。

數(shù)據(jù)一致性的解決方案

在絕大部分業(yè)務(wù)場(chǎng)景中姑尺,追求的是最終一致性雹姊,針對(duì)物理失敗造成的數(shù)據(jù)不一致常用的方案有:消費(fèi)消息異步刪除緩存以及訂閱Binlog的方式,針對(duì)邏輯失敗造成的數(shù)據(jù)不一致常用的方案有:隊(duì)列異步操作同步化

消費(fèi)消息異步刪除緩存

[圖片上傳失敗...(image-ec5eb7-1615694322860)]

訂閱Binlog

[圖片上傳失敗...(image-c27c4c-1615694322860)]

利用隊(duì)列串行化

在分析cache aside pattern發(fā)現(xiàn)在并發(fā)的情況下也會(huì)存在數(shù)據(jù)不一致的場(chǎng)景敦姻,只不過(guò)發(fā)生的概率很低歧杏,另外如果先刪除緩存再更新數(shù)據(jù)庫(kù)在并發(fā)讀寫的情況下也會(huì)存在數(shù)據(jù)不一致的情況犬绒。類似這種由于并發(fā)時(shí)序?qū)е碌臄?shù)據(jù)不一致的情況,都是因?yàn)閷懻?qǐng)求還沒(méi)有結(jié)束讀請(qǐng)求讀取的是舊數(shù)據(jù)茵瘾,如果讀請(qǐng)求在寫請(qǐng)求之后處理,即請(qǐng)求的處理能夠串行化的話圣絮,就能保證讀請(qǐng)求讀到的是寫請(qǐng)求更新的最新的數(shù)據(jù)雕旨。

將請(qǐng)求進(jìn)行串行化,最常用的方式是采用隊(duì)列的方式棒搜,一個(gè)隊(duì)列只能對(duì)應(yīng)一個(gè)工作線程活箕,更新數(shù)據(jù)的寫請(qǐng)求放置隊(duì)列中讹蘑,等待異步處理;讀請(qǐng)求如果能從緩存中獲取數(shù)據(jù),則返回翠拣,如果緩存中沒(méi)有數(shù)據(jù)误墓,就將讀請(qǐng)求放置到隊(duì)列中,等待寫請(qǐng)求數(shù)據(jù)更新完成然想。這種方案需要考慮的問(wèn)題有:

  1. 讀請(qǐng)求長(zhǎng)時(shí)間阻塞:如果隊(duì)列中擠壓了多個(gè)寫請(qǐng)求欣范,則讀請(qǐng)求會(huì)存在長(zhǎng)時(shí)間阻塞的情況,需要設(shè)置超時(shí)處理策略妨蛹,一旦超過(guò)超時(shí)時(shí)間晴竞,則直接讀取數(shù)據(jù)庫(kù)返回,避免長(zhǎng)時(shí)間不響應(yīng)颤难;另外行嗤,在業(yè)務(wù)中需要進(jìn)行壓測(cè),考慮隊(duì)列中在峰值情況下會(huì)積攢多少寫請(qǐng)求捂敌,如果過(guò)多既琴,需要考慮隊(duì)列優(yōu)化的方式和相應(yīng)的解決方案;
  2. 多個(gè)隊(duì)列分散壓力:可以根據(jù)數(shù)據(jù)項(xiàng)通過(guò)hash等路由方式逆济,創(chuàng)建多個(gè)隊(duì)列并行執(zhí)行來(lái)提升系統(tǒng)吞吐量磺箕;
  3. 操作復(fù)雜需要考慮全面:由于采用隊(duì)列來(lái)進(jìn)行串行化松靡,那么要考慮隊(duì)列的可用性,隊(duì)列阻塞以及服務(wù)掛掉后的容災(zāi)恢復(fù)策略是否健壯等等岛马,相對(duì)而言整體的方案需要考慮的點(diǎn)會(huì)有很多屠列;

常見(jiàn)的幾個(gè)場(chǎng)景問(wèn)題:

1)過(guò)期還是不過(guò)期緩存數(shù)據(jù):針對(duì)緩存數(shù)據(jù)是否需要設(shè)置過(guò)期時(shí)間也需要結(jié)合場(chǎng)景來(lái)進(jìn)行分析笛洛,一些長(zhǎng)尾商品,大多數(shù)數(shù)據(jù)在業(yè)務(wù)中都是讀場(chǎng)景更多沟蔑,并且緩存空間很大的話,就可以考慮不過(guò)期數(shù)據(jù)溉贿。那是否就意味著這就是一份靜態(tài)數(shù)據(jù)了浦旱?當(dāng)緩存空間已滿時(shí),數(shù)據(jù)會(huì)根據(jù)淘汰策略移除緩存,另外數(shù)據(jù)更新時(shí)也可以通過(guò)Binlog等其他方式進(jìn)行異步失效緩存例隆。

如果系統(tǒng)通過(guò)消息異步更新操作成本過(guò)高或者依賴于外部系統(tǒng)無(wú)法進(jìn)行訂閱binlog異步更新的話镀层,就需要來(lái)采用過(guò)期緩存數(shù)據(jù)來(lái)保障數(shù)據(jù)最終一致性皿曲。

2)維度化緩存與增量更新:如果一個(gè)實(shí)體包含多個(gè)屬性,在實(shí)體發(fā)生變更時(shí)坞古,如果將所有的屬性全部更新一遍劫樟,這個(gè)成本就很高叠艳,況且只是其中的幾個(gè)屬性發(fā)生變化。因此吃粒,將多個(gè)屬性進(jìn)行各個(gè)維度化進(jìn)行拆解拒课,按照多維度進(jìn)行緩存捕发,更新時(shí)只需要增強(qiáng)更新對(duì)應(yīng)維度即可很魂;

3)大value:大value的問(wèn)題要時(shí)刻警惕,可以考慮將value進(jìn)行壓縮法挨,以及緩存時(shí)進(jìn)行拆解幅聘,然后在業(yè)務(wù)服務(wù)中進(jìn)行數(shù)據(jù)聚合來(lái)避免大value的問(wèn)題帝蒿;

4)熱點(diǎn)緩存問(wèn)題:針對(duì)熱點(diǎn)數(shù)據(jù)如果每次都從遠(yuǎn)程緩存去獲取,會(huì)給緩存系統(tǒng)帶來(lái)過(guò)多的負(fù)載暴氏,會(huì)導(dǎo)致獲取緩存數(shù)據(jù)響應(yīng)過(guò)慢,可以使用緩存集群关带,掛載更多的從緩存沼撕,讀取數(shù)據(jù)從從緩存中獲取务豺。針對(duì)熱點(diǎn)數(shù)據(jù)可以使用應(yīng)用本地緩存來(lái)減少對(duì)遠(yuǎn)程緩存的請(qǐng)求負(fù)載;

5)數(shù)據(jù)預(yù)熱:可以預(yù)先將數(shù)據(jù)加載到緩存中舍败,方式緩存數(shù)據(jù)為空敬拓,大量的請(qǐng)求回源到db乘凸。如果容量很高可以考慮全量預(yù)熱,如果容量?jī)?yōu)先灵嫌,就只能選擇高頻熱點(diǎn)數(shù)據(jù)進(jìn)行數(shù)據(jù)預(yù)熱葛作,還需要關(guān)注是否有批量操作以及慢sql帶來(lái)的性能問(wèn)題赂蠢,在整個(gè)數(shù)據(jù)預(yù)熱過(guò)程中需要有可靠的監(jiān)控機(jī)制來(lái)保障;

6)非預(yù)期熱點(diǎn)數(shù)據(jù):針對(duì)業(yè)務(wù)預(yù)估不足的熱點(diǎn)數(shù)據(jù)玖院,需要有熱點(diǎn)發(fā)現(xiàn)系統(tǒng)來(lái)統(tǒng)計(jì)熱點(diǎn)key第岖,實(shí)時(shí)監(jiān)控非預(yù)期的熱點(diǎn)數(shù)據(jù)蔑滓,可以將這些key推到本地緩存中遇绞,防止預(yù)估不足的熱點(diǎn)key拖垮遠(yuǎn)程緩存服務(wù)猎塞。

7)緩存實(shí)例故障快速恢復(fù):當(dāng)某一個(gè)緩存實(shí)例故障后荠耽,緩存一般是采用分片實(shí)例存儲(chǔ),假設(shè)緩存key路由策略采用的取模機(jī)制的話倘屹,會(huì)導(dǎo)致當(dāng)前實(shí)例的流量迅速到達(dá)db層慢叨,這種情況可以采用主從機(jī)制拍谐,當(dāng)一個(gè)實(shí)例故障后其他實(shí)例可以使用,但是這種方式的問(wèn)題在于水平擴(kuò)展不夠践瓷,如果分片實(shí)例上增加一個(gè)節(jié)點(diǎn)的話亡蓉,會(huì)導(dǎo)致緩存命中率迅速下降砍濒。

如果key路由策略采用的一致性哈希的話,某一個(gè)實(shí)例節(jié)點(diǎn)故障樊卓,只會(huì)導(dǎo)致哈希環(huán)上的部分緩存不命中不會(huì)導(dǎo)致大量請(qǐng)求到達(dá)db简识,但是針對(duì)熱點(diǎn)數(shù)據(jù)的話感猛,可能會(huì)導(dǎo)致改節(jié)點(diǎn)負(fù)載過(guò)高成為系統(tǒng)瓶頸奢赂。針對(duì)實(shí)例故障恢復(fù)的方式有:1. 主從機(jī)制膳灶,對(duì)數(shù)據(jù)進(jìn)行備份立由,盡可能保障有可用數(shù)據(jù)锐膜;2. 服務(wù)降低弛房,新增緩存實(shí)例然后異步線程預(yù)熱數(shù)據(jù);3. 可以先采用一致性哈希路由策略荷逞,當(dāng)出現(xiàn)熱點(diǎn)數(shù)據(jù)時(shí)到達(dá)某個(gè)閾值時(shí)降級(jí)為取模的策略种远。

多級(jí)緩存設(shè)計(jì)案例

從用戶發(fā)出請(qǐng)求到到最底層的數(shù)據(jù)庫(kù)實(shí)際上會(huì)經(jīng)歷很多節(jié)點(diǎn)顽耳,因此在整個(gè)鏈路上都可以設(shè)置緩存射富,并且按照緩存最近原則將緩存放置在里用戶最近的地方提升系統(tǒng)響應(yīng)的效果最為明顯,相應(yīng)的提升系統(tǒng)吞吐量的效果就越為顯著弄抬,通過(guò)能夠大大降低對(duì)后端的壓力宪郊。整個(gè)鏈路流程里可以添加緩存的地方有:發(fā)起請(qǐng)求->瀏覽器/客戶端緩存->邊緣緩存/CDN->反向代理(nginx)緩存->遠(yuǎn)程緩存->進(jìn)程內(nèi)緩存->數(shù)據(jù)庫(kù)緩存弛槐。服務(wù)端多級(jí)緩存設(shè)計(jì)通用的技術(shù)方案如下:

[圖片上傳失敗...(image-32078-1615694322860)]

Binlog:
binlog是MySQL server層維護(hù)的一種二進(jìn)制日志,主要用來(lái)記錄對(duì)mysql數(shù)據(jù)更新或潛在發(fā)生更新的SQL語(yǔ)句店枣,并以事務(wù)的形式保存在磁盤中;
主要作用有:

  • 復(fù)制:MySQL Replication在Master端開(kāi)啟binlog,master把它的二進(jìn)制日志傳遞給slaves并回訪來(lái)達(dá)到master-slave數(shù)據(jù)一致的目的
  • 數(shù)據(jù)恢復(fù):通過(guò)mysql binlog工具恢復(fù)數(shù)據(jù)
  • 增量備份

查看binlog日志文件位置

show variables like '%log_bin%';
-- 查看binlog格式
show variables like 'binlog_format';

攜程機(jī)票訂單緩存方案

為了解決數(shù)據(jù)一致性問(wèn)題鸯两,我們?cè)O(shè)計(jì)了兩套方案來(lái)更新緩存數(shù)據(jù)长豁,保證緩存數(shù)據(jù)的實(shí)時(shí)性匠襟。兩套方案相互補(bǔ)充该园,避免其一短暫失效而產(chǎn)生一致性問(wèn)題里初。

方案一的思路是掃描數(shù)據(jù)庫(kù)的數(shù)據(jù)變化記錄忽舟,比如數(shù)據(jù)表里面的數(shù)據(jù)更新時(shí)間戳萧诫,或者訂閱數(shù)據(jù)庫(kù)的binlog記錄。當(dāng)掃描到數(shù)據(jù)變化時(shí)哑诊,刪除對(duì)應(yīng)的緩存數(shù)據(jù)镀裤。

方案二的思路是借助于攜程的消息通知平臺(tái)服務(wù)缴饭。在訂單處理流轉(zhuǎn)的各個(gè)重要環(huán)節(jié),會(huì)有消息事件產(chǎn)生颗搂。通過(guò)訂閱這些消息丢氢,能夠感知到訂單數(shù)據(jù)的變化,并且通過(guò)對(duì)不同消息的影響數(shù)據(jù)范圍可以精準(zhǔn)地配置緩存數(shù)據(jù)更新蒸走。

兩套方案的并行實(shí)施比驻,保證了緩存數(shù)據(jù)的延遲控制在了100毫秒以內(nèi)岛抄。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末夫椭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子猾漫,更是在濱河造成了極大的恐慌悯周,老刑警劉巖陪竿,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件族跛,死亡現(xiàn)場(chǎng)離奇詭異礁哄,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)夺脾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門咧叭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)烁竭,“玉大人派撕,你說(shuō)我怎么就攤上這事÷黼剩” “怎么了佩脊?”我有些...
    開(kāi)封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵威彰,是天一觀的道長(zhǎng)穴肘。 經(jīng)常有香客問(wèn)我,道長(zhǎng)豹缀,這世上最難降的妖魔是什么邢笙? 我笑而不...
    開(kāi)封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任氮惯,我火速辦了婚禮,結(jié)果婚禮上帘不,老公的妹妹穿的比我還像新娘杨箭。我一直安慰自己告唆,他們只是感情好棺弊,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著擒悬,像睡著了一般模她。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上懂牧,一...
    開(kāi)封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天侈净,我揣著相機(jī)與錄音,去河邊找鬼僧凤。 笑死畜侦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的旋膳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼途事,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼验懊!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起尸变,我...
    開(kāi)封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤义图,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后召烂,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體碱工,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了怕篷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片历筝。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖廊谓,靈堂內(nèi)的尸體忽然破棺而出漫谷,到底是詐尸還是另有隱情,我是刑警寧澤蹂析,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站碟婆,受9級(jí)特大地震影響电抚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜竖共,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一蝙叛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧公给,春花似錦借帘、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至腿准,卻和暖如春际起,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背吐葱。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工街望, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人弟跑。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓灾前,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親孟辑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子哎甲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容