分庫(kù)分表實(shí)戰(zhàn)之流量激增帶來(lái)的技術(shù)挑戰(zhàn)
前 言
??接上期??,到現(xiàn)在為止,我們已經(jīng)對(duì)訂單系統(tǒng)核心接口業(yè)務(wù)流程有了一定的了解,此時(shí)我們可以接一些簡(jiǎn)單的需求做了。
同時(shí)這個(gè)時(shí)候,也會(huì)有對(duì)應(yīng)的產(chǎn)品經(jīng)理來(lái)和我們對(duì)接需求,一般3個(gè)月左右,我們處理單系統(tǒng)的日常需求就輕車熟路了。
可能在剛?cè)肼毜臅r(shí)候,這家初創(chuàng)型互聯(lián)網(wǎng)公司累積的用戶量也就10萬(wàn),每天活躍2萬(wàn),日訂單2萬(wàn),如下圖:
對(duì)于數(shù)據(jù)庫(kù)中的訂單表而言,如果按照一天2萬(wàn)個(gè)訂單數(shù)據(jù)量計(jì)算,一年也就七八百萬(wàn)的訂單量,還是可以輕松hold住的。
行業(yè)風(fēng)口,用戶量突增帶來(lái)的問(wèn)題
但是,可能若我們就是這么幸運(yùn),剛好遇到了移動(dòng)互聯(lián)網(wǎng)快速發(fā)展的幾年。
這個(gè)時(shí)候,外賣APP的用戶量迅速增長(zhǎng)到了100萬(wàn),日活用戶20萬(wàn),日訂單20萬(wàn),訂單單表也從300萬(wàn)快速達(dá)到了2000萬(wàn),如下圖:
在這3個(gè)月的過(guò)程中,我們除了做日常的需求外,還要支持解決線上問(wèn)題,所以經(jīng)常會(huì)去查詢訂單表。
在查詢訂單表數(shù)據(jù)的時(shí)候,我們會(huì)發(fā)現(xiàn)隨著訂單數(shù)據(jù)的增多,訂單查詢sql相應(yīng)的也會(huì)變得越來(lái)越慢,比如,你剛?cè)肼毜臅r(shí)候單表可能就300萬(wàn)數(shù)據(jù)量,查詢只需要20ms的樣子,但是現(xiàn)在,單表增長(zhǎng)到2000萬(wàn),不過(guò)查詢一般也都穩(wěn)定在200ms以下。
某一天,當(dāng)我們正在沉浸式地寫(xiě)著代碼時(shí),leader突然找到我們說(shuō):“昨天晚上小猛上了一個(gè)需求,然后今天突然發(fā)現(xiàn)我們訂單sql查詢超過(guò)了3s,肯定是昨晚上線的sql有問(wèn)題,現(xiàn)在我們單表才2000萬(wàn)數(shù)據(jù),MySQL是可以輕松hold住的,小猛今天不在公司,你幫忙排查下問(wèn)題,然后優(yōu)化下sql?!?/p>
可以想象一下這樣一個(gè)場(chǎng)景,當(dāng)我們打開(kāi)一個(gè)外賣app想點(diǎn)個(gè)外賣,想起來(lái)上周吃的某個(gè)外賣還不錯(cuò),就想看看自己點(diǎn)的是哪個(gè)商家的外賣,然后滿心歡喜的想要點(diǎn)開(kāi)自己的歷史訂單列表。
結(jié)果等了3s訂單列表都還沒(méi)加載出來(lái),也許作為干飯人的我們有著強(qiáng)大的毅力,最后終于等到訂單列表加載出來(lái)了,心滿意足選好菜品下單。
但此時(shí)我們的腦海中是不是會(huì)出現(xiàn)那個(gè)bgm:“完了,芭比Q了”,所以這樣的查詢速度是萬(wàn)萬(wàn)不能接受的,因?yàn)轶w驗(yàn)極差。
回過(guò)神來(lái)的我們,聽(tīng)完leader說(shuō)的話后就接下了這個(gè)任務(wù),馬上開(kāi)始著手優(yōu)化sql了,但是下一秒就遇到一個(gè)新的難題,那就是我們根本沒(méi)優(yōu)化過(guò)sql,就連MySQL的一次查詢會(huì)經(jīng)歷過(guò)哪些過(guò)程,你都不是很清楚,更不用提要從哪里開(kāi)始優(yōu)化了。
而sql優(yōu)化的第一步,我們得要先了解一下MySQL一次完整查詢會(huì)經(jīng)歷哪些過(guò)程,然后再針對(duì)性的優(yōu)化,MySQL一次完整的查詢的過(guò)程呢,我們?cè)谙乱黄恼聲?huì)詳細(xì)的分析,大家不要著急,這里我們繼續(xù)分析下現(xiàn)狀。
偶爾的流量爆發(fā),問(wèn)題被進(jìn)一步放大
根據(jù)剛才的分析,在上百萬(wàn)規(guī)模的一個(gè)用戶群體下,數(shù)據(jù)庫(kù)中一年的訂單數(shù)據(jù)量搞不好都要上億了,一旦訂單表中的數(shù)據(jù)達(dá)到這樣的一個(gè)量級(jí)之后,后續(xù)訂單sql的性能就開(kāi)始顯著下降了。
但是,容易被我們忽視的一個(gè)場(chǎng)景就是,流量可能偶爾會(huì)爆發(fā)一下,然后sql查詢較慢的問(wèn)題會(huì)被進(jìn)一步的放大,那么哪些場(chǎng)景會(huì)導(dǎo)致流量在短時(shí)間內(nèi)爆發(fā)呢?
其實(shí)這種場(chǎng)景就比較多了,比如某一天,我們的外賣APP做了一些促銷活動(dòng),或者是某一天競(jìng)對(duì)的APP不幸掛掉了(作為良性競(jìng)爭(zhēng)倡導(dǎo)者的我們不應(yīng)該有這種想法,但是萬(wàn)一呢,是吧?),這些場(chǎng)景下,大量的流量就會(huì)在短時(shí)間里引爆我們外賣APP。
好的,那我們這里假設(shè)就是競(jìng)對(duì)的外賣APP出了一些故障吧,比如競(jìng)對(duì)的評(píng)價(jià)系統(tǒng)掛掉了,導(dǎo)致店鋪的評(píng)價(jià)顯示不出來(lái),那這就嚴(yán)重了,因?yàn)椴糠钟脩舻挠啿土?xí)慣,是在點(diǎn)外賣前都會(huì)先看下店鋪的評(píng)價(jià)。
結(jié)果由于競(jìng)對(duì)外賣APP的評(píng)價(jià)系統(tǒng)掛了,導(dǎo)致店鋪的評(píng)價(jià)顯示不出來(lái),那這些用戶可能就都會(huì)跑到我們的外賣APP來(lái)下單,這個(gè)時(shí)候,我們外賣APP的流量就會(huì)瞬間增大好幾倍。
本來(lái)這個(gè)時(shí)候,我們訂單表一次查詢差不多都需要3s了,現(xiàn)在又發(fā)生了流量突增的情況,那就會(huì)導(dǎo)致已經(jīng)存在的問(wèn)題被進(jìn)一步的放大,比如一次訂單查詢會(huì)直接變?yōu)?s,這都是有可能的。
所以,如果我們不對(duì)這種場(chǎng)景進(jìn)行優(yōu)化,就會(huì)失去一些用戶,因?yàn)槲覀冏约旱耐赓uAPP此時(shí)也很卡的話,我們就可能會(huì)錯(cuò)過(guò)一次“天賜良機(jī)”。
結(jié)束語(yǔ)
不過(guò),對(duì)于這種千萬(wàn)級(jí)數(shù)據(jù)的優(yōu)化大家也不用著急,因?yàn)榻酉聛?lái),我們會(huì)帶著大家一步步分析這些問(wèn)題背后的原因,并且會(huì)將對(duì)應(yīng)的解決方案進(jìn)行落地,所以大家一定要好好學(xué)習(xí),畢竟機(jī)會(huì)從來(lái)都是留給有準(zhǔn)備的人的。