之前更新過一個(gè)“億級(jí)流量系統(tǒng)架構(gòu)”系列,主要講述了一個(gè)大規(guī)模商家數(shù)據(jù)平臺(tái)的如下幾個(gè)方面:
如何承載百億級(jí)數(shù)據(jù)存儲(chǔ)
如何設(shè)計(jì)高容錯(cuò)的分布式架構(gòu)
如何設(shè)計(jì)承載百億流量的高性能架構(gòu)
如何設(shè)計(jì)每秒數(shù)十萬并發(fā)查詢的高并發(fā)架構(gòu)
如何設(shè)計(jì)全鏈路99.99%高可用架構(gòu)。
接下來,我們將會(huì)繼續(xù)通過幾篇文章,對(duì)這套系統(tǒng)的可擴(kuò)展架構(gòu)、數(shù)據(jù)一致性保障等方面進(jìn)行探討。
如果沒看過本系列文章的同學(xué)可以先回過頭看看之前寫的幾篇文章:
億級(jí)流量系統(tǒng)架構(gòu)
如果大家看過之前的一系列文章,應(yīng)該依稀還記得上一篇文章最后,整個(gè)系統(tǒng)架構(gòu)大致演進(jìn)到了如下圖的一個(gè)狀態(tài)。
如果沒看過之前的系列文章,上來猛一看下面這個(gè)圖,絕對(duì)一臉懵逼,就看到一片“花花綠綠”。這個(gè)也沒辦法,復(fù)雜的系統(tǒng)架構(gòu)都是特別的龐雜的。
好,咱們正式開始!這篇文章咱們來聊聊這套系統(tǒng)里的不同子系統(tǒng)之間通信過程的一個(gè)可擴(kuò)展性的架構(gòu)處理。
這里面蘊(yùn)含了線上復(fù)雜系統(tǒng)之間交互的真實(shí)場(chǎng)景和痛點(diǎn),相信對(duì)大家能夠有所啟發(fā)。
我們就關(guān)注一下上面的架構(gòu)圖里左側(cè)的部分,處于中間位置的那個(gè)實(shí)時(shí)計(jì)算平臺(tái)在完成了每一個(gè)數(shù)據(jù)分片的計(jì)算過后,都會(huì)將計(jì)算結(jié)果寫入到最左側(cè)的數(shù)據(jù)查詢平臺(tái)中。
出于種種考量,因?yàn)橛?jì)算結(jié)果的數(shù)據(jù)量相比于原始數(shù)據(jù)的數(shù)據(jù)量,實(shí)際上已經(jīng)少了一個(gè)數(shù)量級(jí)了。
所以,我們選擇的是實(shí)時(shí)計(jì)算平臺(tái)直接將數(shù)據(jù)寫入到數(shù)據(jù)查詢平臺(tái)的MySQL數(shù)據(jù)庫集群中,然后數(shù)據(jù)查詢平臺(tái)基于MySQL數(shù)據(jù)庫集群來對(duì)外提供查詢請(qǐng)求。
此外,為了保證當(dāng)天的實(shí)時(shí)計(jì)算結(jié)果能夠高并發(fā)的被用戶查詢,因此當(dāng)時(shí)采取的是實(shí)時(shí)計(jì)算平臺(tái)的計(jì)算結(jié)果同時(shí)雙寫緩存集群和數(shù)據(jù)庫集群。
這樣,數(shù)據(jù)查詢平臺(tái)可以優(yōu)先走緩存集群,如果找不到緩存才會(huì)從數(shù)據(jù)庫集群里回查數(shù)據(jù)。
所以上述就是實(shí)時(shí)計(jì)算平臺(tái)與數(shù)據(jù)查詢平臺(tái)之間在某一個(gè)時(shí)期的一個(gè)典型的系統(tǒng)耦合架構(gòu)。
兩個(gè)不同的系統(tǒng)之間,通過同一套數(shù)據(jù)存儲(chǔ)(數(shù)據(jù)庫集群+緩存集群)進(jìn)行了耦合。
大家看看下面的圖,再來清晰的感受一下系統(tǒng)之間耦合的感覺。
系統(tǒng)耦合痛點(diǎn)1:被動(dòng)承擔(dān)的高并發(fā)寫入壓力
大家如果仔細(xì)看過之前的系列文章,大概就該知道,在早期主要是集中精力對(duì)實(shí)時(shí)計(jì)算平臺(tái)的架構(gòu)做了大量的演進(jìn),以便于讓他可以支撐超高并發(fā)寫入、海量數(shù)據(jù)的超高性能計(jì)算,最后就可以抗住每秒數(shù)萬甚至數(shù)十萬的數(shù)據(jù)涌入的存儲(chǔ)和計(jì)算。
但是因?yàn)樵缙诓捎昧松蠄D的這種最簡(jiǎn)單、最高效、最實(shí)用的耦合交互方式,實(shí)時(shí)計(jì)算平臺(tái)直接把每個(gè)數(shù)據(jù)分片計(jì)算完的結(jié)果寫入共享存儲(chǔ)中,就導(dǎo)致了一個(gè)很大的問題。
實(shí)時(shí)計(jì)算平臺(tái)能抗住超高并發(fā)寫入沒問題了,而且還能快速的高性能計(jì)算也沒問題。
但是,他同時(shí)會(huì)隨著數(shù)據(jù)量的增長(zhǎng),越來越高并發(fā)的將計(jì)算結(jié)果寫入到一個(gè)數(shù)據(jù)庫集群中。而這個(gè)數(shù)據(jù)庫集群在團(tuán)隊(duì)劃分的時(shí)候,實(shí)際上是交給數(shù)據(jù)查詢平臺(tái)團(tuán)隊(duì)來負(fù)責(zé)維護(hù)的。
也就是說,對(duì)實(shí)時(shí)計(jì)算平臺(tái)團(tuán)隊(duì)來說,他們是不care那個(gè)數(shù)據(jù)庫集群是什么狀態(tài)的,而就是不停的把數(shù)據(jù)寫入到那個(gè)集群里去。
但是,對(duì)于數(shù)據(jù)查詢平臺(tái)團(tuán)隊(duì)來說,他們就會(huì)被動(dòng)的承擔(dān)實(shí)時(shí)計(jì)算平臺(tái)越來越高并發(fā)壓力寫入的數(shù)據(jù)。
這個(gè)時(shí)候數(shù)據(jù)查詢平臺(tái)團(tuán)隊(duì)的同學(xué)很可能處于這樣的一種焦躁中:本來自己這塊系統(tǒng)也有很多架構(gòu)上的改進(jìn)點(diǎn)要做,比如說之前提到的冷數(shù)據(jù)查詢引擎的自研。
但是呢,他們卻要不停的被線上數(shù)據(jù)庫服務(wù)器的報(bào)警搞的焦頭爛額,疲于奔命。
因?yàn)閿?shù)據(jù)庫服務(wù)器單機(jī)寫入壓力可能隨著業(yè)務(wù)增長(zhǎng),迅速變成每秒5000~6000的寫入壓力,每天到了高峰期,線上服務(wù)器的CPU、磁盤、IO、網(wǎng)絡(luò)等壓力巨大,報(bào)警頻繁。
此時(shí)數(shù)據(jù)查詢平臺(tái)團(tuán)隊(duì)的架構(gòu)演進(jìn)節(jié)奏就會(huì)被打亂,因?yàn)楸仨毐粍?dòng)的去根據(jù)實(shí)時(shí)計(jì)算平臺(tái)的寫入壓力來進(jìn)行調(diào)整,必須立馬停下手中的工作,然后去考慮如何對(duì)數(shù)據(jù)庫集群做分庫分表的方案,如何對(duì)表進(jìn)行擴(kuò)容,如何對(duì)庫進(jìn)行擴(kuò)容。
同時(shí)結(jié)合分庫分表的方案,數(shù)據(jù)查詢平臺(tái)自身的查詢機(jī)制又要跟著一起改變,大量的改造工作,調(diào)研工作,數(shù)據(jù)遷移工作,上線部署工作,代碼改造工作。
實(shí)際上,上面說的這種情況,絕對(duì)是不合理的。
因?yàn)檎麄€(gè)這套數(shù)據(jù)平臺(tái)是一個(gè)大互聯(lián)網(wǎng)公司里核心業(yè)務(wù)部門的一個(gè)核心系統(tǒng),他是數(shù)十個(gè)Java工程師與大數(shù)據(jù)工程師通力合作一起開發(fā),而且里面劃分為了多個(gè)team。
比如說數(shù)據(jù)接入系統(tǒng)是一個(gè)團(tuán)隊(duì)負(fù)責(zé),實(shí)時(shí)計(jì)算平臺(tái)是一個(gè)團(tuán)隊(duì)負(fù)責(zé),數(shù)據(jù)查詢平臺(tái)是一個(gè)團(tuán)隊(duì)負(fù)責(zé),離線數(shù)據(jù)倉(cāng)庫是一個(gè)團(tuán)隊(duì)負(fù)責(zé),等等。
所以只要分工合作了以后,那么就不應(yīng)該讓一個(gè)團(tuán)隊(duì)被動(dòng)的去承擔(dān)另外一個(gè)團(tuán)隊(duì)猛然增長(zhǎng)的寫入壓力,這樣會(huì)打破每個(gè)團(tuán)隊(duì)自己的工作節(jié)奏。
導(dǎo)致這個(gè)問題的根本原因,就是因?yàn)閮蓚€(gè)系統(tǒng)間,沒有做任何解耦的處理。
這就導(dǎo)致數(shù)據(jù)查詢平臺(tái)團(tuán)隊(duì)根本無法對(duì)實(shí)時(shí)計(jì)算平臺(tái)涌入過來的數(shù)據(jù)做任何有效的控制和管理,這也導(dǎo)致了“被動(dòng)承擔(dān)高并發(fā)寫入壓力”問題的發(fā)生。
這種系統(tǒng)耦合導(dǎo)致的被動(dòng)高并發(fā)寫入壓力還不只是上面那么簡(jiǎn)單,實(shí)際在上述場(chǎng)景中,線上生產(chǎn)環(huán)境還發(fā)生過各種奇葩的事情:
某一次線上突然產(chǎn)生大量的熱數(shù)據(jù),熱數(shù)據(jù)計(jì)算結(jié)果涌入數(shù)據(jù)查詢平臺(tái),因?yàn)闆]做任何管控,幾乎一瞬間導(dǎo)致某臺(tái)數(shù)據(jù)庫服務(wù)器寫入并發(fā)達(dá)到1萬+,DBA焦急的擔(dān)心數(shù)據(jù)庫快宕機(jī)了,所有人也都被搞的焦頭爛額,心理崩潰。
系統(tǒng)耦合痛點(diǎn)2:數(shù)據(jù)庫運(yùn)維操作導(dǎo)致的線上系統(tǒng)性能劇烈抖動(dòng)
在這種系統(tǒng)耦合的場(chǎng)景下,反過來實(shí)時(shí)計(jì)算平臺(tái)團(tuán)隊(duì)的同學(xué)其實(shí)心里也會(huì)吶喊:我們心里也苦??!
因?yàn)榉催^來大家可以思考一下,線上數(shù)據(jù)庫中的表結(jié)構(gòu)改變,那幾乎可以說是再正常不過了,尤其是高速迭代發(fā)展中的業(yè)務(wù)。
需求評(píng)審會(huì)上,要是不小心碰上某個(gè)產(chǎn)品經(jīng)理,今天改需求,明天改需求。工程師估計(jì)會(huì)怒火沖天的想要砍人。但是沒辦法,最后還是得為五斗米折腰,該改的需求還是得改。該改的表結(jié)構(gòu)也還是要改,改加的索引也還是要加。
但是大家考慮一個(gè)點(diǎn),如果說對(duì)上述這種強(qiáng)耦合的系統(tǒng)架構(gòu),單表基本都是在千萬級(jí)別的數(shù)據(jù)量,同時(shí)還有單臺(tái)數(shù)據(jù)庫服務(wù)器每秒幾千的寫入壓力。
在這種場(chǎng)景下,在線上走一個(gè)MySQL的DDL語句試一試?奉勸大家千萬別胡亂嘗試,因?yàn)閿?shù)據(jù)查詢團(tuán)隊(duì)里的年輕同學(xué),干過這個(gè)事兒。
實(shí)際的結(jié)果就是,DDL咔嚓一執(zhí)行,對(duì)線上表結(jié)構(gòu)進(jìn)行修改,直接導(dǎo)致實(shí)時(shí)計(jì)算平臺(tái)的寫入數(shù)據(jù)庫的性能急劇下降10倍以上。。。
然后連帶導(dǎo)致實(shí)時(shí)計(jì)算平臺(tái)的數(shù)據(jù)分片計(jì)算任務(wù)大量的延遲。再然后,因?yàn)閷?shí)時(shí)計(jì)算之后的數(shù)據(jù)無法盡快反饋到存儲(chǔ)中,無法被用戶查詢到,導(dǎo)致了大量的線上投訴。
并且,DDL語句執(zhí)行的還特別的慢,耗時(shí)數(shù)十分鐘才執(zhí)行完畢,這就導(dǎo)致數(shù)十分鐘里,整套系統(tǒng)出現(xiàn)了大規(guī)模的計(jì)算延遲,數(shù)據(jù)延遲。
一直到數(shù)十分鐘之后DDL語句執(zhí)行完畢,實(shí)時(shí)計(jì)算平臺(tái)才通過自身的自動(dòng)延遲調(diào)度恢復(fù)機(jī)制慢慢恢復(fù)了正常的計(jì)算。
orz......于是從此之后,數(shù)據(jù)查詢平臺(tái)的攻城獅,必須得小心翼翼的在每天凌晨2點(diǎn)~3點(diǎn)之間進(jìn)行相關(guān)的數(shù)據(jù)庫運(yùn)維操作,避免影響線上系統(tǒng)的性能穩(wěn)定性。
但是,難道人家年輕工程師沒有女朋友?難道年長(zhǎng)工程師沒有老婆孩子?經(jīng)常在凌晨3點(diǎn)看看窗外的風(fēng)景,然后打個(gè)滴滴回家,估計(jì)沒任何人愿意。
其實(shí)上述問題,說白了,還是因?yàn)閮商紫到y(tǒng)直接通過存儲(chǔ)耦合在了一起,導(dǎo)致了任何一個(gè)系統(tǒng)只要有點(diǎn)異動(dòng),直接就會(huì)影響另外一個(gè)系統(tǒng)。耦合!耦合!還是耦合!
系統(tǒng)耦合痛點(diǎn)N。。。
其實(shí)上面只不過是挑了其中兩個(gè)系統(tǒng)耦合痛點(diǎn)來說明而已,文章篇幅有限,很難把上述長(zhǎng)達(dá)數(shù)月的耦合狀態(tài)下的各種痛點(diǎn)一一說明,實(shí)際線上生產(chǎn)環(huán)境的痛點(diǎn)還包括不限于:
實(shí)時(shí)計(jì)算平臺(tái)自身寫入機(jī)制有bug導(dǎo)致的數(shù)據(jù)丟失,結(jié)果讓數(shù)據(jù)查詢平臺(tái)的同學(xué)去排查;
實(shí)時(shí)計(jì)算平臺(tái)對(duì)緩存集群和數(shù)據(jù)庫集群進(jìn)行雙寫的時(shí)候,雙寫一致性的保證機(jī)制,居然還需要自己來實(shí)現(xiàn),直接導(dǎo)致自己的代碼里混合了大量不屬于自己的業(yè)務(wù)邏輯;
數(shù)據(jù)查詢平臺(tái)有時(shí)候做了分庫分表運(yùn)維操作之后,比如擴(kuò)容庫和表,居然還得讓實(shí)時(shí)計(jì)算平臺(tái)的同學(xué)配合著一起修改代碼配置,一起測(cè)試和部署上線
數(shù)據(jù)查詢平臺(tái)和實(shí)時(shí)計(jì)算平臺(tái)兩個(gè)team的同學(xué)在上述大量耦合場(chǎng)景下,經(jīng)常天天一起加班到凌晨深夜,各自的女朋友都以為他們打算在一起了,但實(shí)際情況是一堆大老爺兒們天天被搞的焦頭爛額,苦不堪言,都不愿意多看對(duì)方一眼
因?yàn)橄到y(tǒng)耦合導(dǎo)致的各種問題,兩個(gè)team都要抽時(shí)間精力來解決,影響了自己那套系統(tǒng)的架構(gòu)演進(jìn)進(jìn)度,沒法集中人力和時(shí)間做真正有價(jià)值和意義的事情
下一篇文章,我們就來聊一聊針對(duì)這些痛點(diǎn),如何靈活的運(yùn)用MQ消息中間件技術(shù)來進(jìn)行復(fù)雜系統(tǒng)之間的解耦,同時(shí)解耦過后如何來自行對(duì)流量數(shù)據(jù)進(jìn)行管控,解決各種系統(tǒng)耦合的問題。
聯(lián)系客服