自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

別光看NB的Github開源項(xiàng)目,你得參考他們?nèi)ピO(shè)計(jì)自己的架構(gòu)

開發(fā) 架構(gòu)
這篇文章就聊聊這個(gè)數(shù)據(jù)產(chǎn)品背后對應(yīng)的一套大型商家數(shù)據(jù)平臺,看看這個(gè)平臺在分布式、高并發(fā)、高可用、高性能、海量數(shù)據(jù)等技術(shù)挑戰(zhàn)下的架構(gòu)演進(jìn)歷程。

一、背景引入

首先簡單介紹一下項(xiàng)目背景,公司對合作商家提供一個(gè)付費(fèi)級產(chǎn)品,這個(gè)商業(yè)產(chǎn)品背后涉及到數(shù)百人的研發(fā)團(tuán)隊(duì)協(xié)作開發(fā),包括各種業(yè)務(wù)系統(tǒng)來提供很多強(qiáng)大的業(yè)務(wù)功能,同時(shí)在整個(gè)平臺中包含了一個(gè)至關(guān)重要的核心數(shù)據(jù)產(chǎn)品,這個(gè)數(shù)據(jù)產(chǎn)品的定位是全方位支持用戶的業(yè)務(wù)經(jīng)營和快速?zèng)Q策。

這篇文章就聊聊這個(gè)數(shù)據(jù)產(chǎn)品背后對應(yīng)的一套大型商家數(shù)據(jù)平臺,看看這個(gè)平臺在分布式、高并發(fā)、高可用、高性能、海量數(shù)據(jù)等技術(shù)挑戰(zhàn)下的架構(gòu)演進(jìn)歷程。

因?yàn)檎紫到y(tǒng)規(guī)模過于龐大,涉及研發(fā)人員很多,持續(xù)時(shí)間很長,文章難以表述出其中各種詳細(xì)的技術(shù)細(xì)節(jié)以及方案,因此本文主要從整體架構(gòu)演進(jìn)的角度來闡述。

至于選擇這個(gè)商家數(shù)據(jù)平臺項(xiàng)目來聊架構(gòu)演進(jìn)過程,是因?yàn)檫@個(gè)平臺基本跟業(yè)務(wù)耦合度較低,不像我們負(fù)責(zé)過的C端類的電商平臺以及其他業(yè)務(wù)類平臺有那么重的業(yè)務(wù)在里面,文章可以專注闡述技術(shù)架構(gòu)的演進(jìn),不需要牽扯太多的業(yè)務(wù)細(xì)節(jié)。

此外,這個(gè)平臺項(xiàng)目在筆者帶的團(tuán)隊(duì)負(fù)責(zé)過的眾多項(xiàng)目中,相對算比較簡單的,但是前后又涉及到各種架構(gòu)的演進(jìn)過程,因此很適合通過文字的形式來展現(xiàn)出來。

二、商家數(shù)據(jù)平臺的業(yè)務(wù)流程

下面幾點(diǎn),是這個(gè)數(shù)據(jù)產(chǎn)品最核心的業(yè)務(wù)流程:

  • 每天從用戶使用的大量業(yè)務(wù)系統(tǒng)中實(shí)時(shí)的采集過來各種業(yè)務(wù)數(shù)據(jù)。
  • 接著存儲在自己的數(shù)據(jù)中心里。
  • 然后實(shí)時(shí)的運(yùn)算大量的幾百行~上千行的SQL來生成各種數(shù)據(jù)報(bào)表。
  • 最后就可以提供這些數(shù)據(jù)報(bào)表給用戶來分析。

基本上用戶在業(yè)務(wù)系統(tǒng)使用過程中,只要數(shù)據(jù)一有變動(dòng),立馬就反饋到各種數(shù)據(jù)報(bào)表中,用戶立馬就可以看到數(shù)據(jù)報(bào)表中的各種變化,進(jìn)而快速的指導(dǎo)自己的決策和管理。

整個(gè)過程,大家看看下面的圖就明白了。

三、從0到1的過程中上線的最low版本

看著上面那張圖好像非常的簡單,是不是?

看整個(gè)過程,似乎數(shù)據(jù)平臺只要想個(gè)辦法把業(yè)務(wù)系統(tǒng)的數(shù)據(jù)采集過來,接著放在MySQL的各種表里,直接咔嚓一下運(yùn)行100多個(gè)幾百行的大SQL,然后SQL運(yùn)行結(jié)果再寫到另外一些MySQL的表里作為報(bào)表數(shù)據(jù),接著用戶直接點(diǎn)擊報(bào)表頁面查詢MySQL里的報(bào)表數(shù)據(jù),就可以了!

其實(shí)任何一個(gè)系統(tǒng)從0到1的過程,都是比較low的,剛開始為了快速開發(fā)出來這個(gè)數(shù)據(jù)平臺,還真的就是用了這種架構(gòu)來開發(fā),大家看下面的圖。

其實(shí)在剛開始業(yè)務(wù)量很小,請求量很小,數(shù)據(jù)量很小的時(shí)候,上面那種架構(gòu)也沒啥問題,還挺簡單的。

我們直接基于自己研發(fā)的數(shù)據(jù)庫binlog采集中間件(這個(gè)是另外一套復(fù)雜系統(tǒng)了,不在本文討論的范圍里,以后有機(jī)會可以聊聊),感知各個(gè)業(yè)務(wù)系統(tǒng)的數(shù)據(jù)庫中的數(shù)據(jù)變更,毫秒級同步到數(shù)據(jù)平臺自己的MySQL庫里。

接著數(shù)據(jù)平臺里做一些定時(shí)調(diào)度任務(wù),每隔幾秒鐘就運(yùn)行上百個(gè)復(fù)雜大SQL,計(jì)算各種報(bào)表的數(shù)據(jù)并將結(jié)果存儲到MySQL庫中。

最后用戶只要對報(bào)表刷新一下,立馬就可以從MySQL庫里查到最新的報(bào)表數(shù)據(jù)。

基本上在無任何技術(shù)挑戰(zhàn)的前提下,這套簡易架構(gòu)運(yùn)行的會很順暢,效果很好。然而,事情往往不是我們想的那么簡單的,因?yàn)榇蠹叶贾绹鴥?nèi)那些互聯(lián)網(wǎng)巨頭公司最大的優(yōu)勢和資源之一,就是有豐富以及海量的C端用戶以及B端的合作商家。

對C端用戶,任何一個(gè)互聯(lián)網(wǎng)巨頭推出一個(gè)新的C端產(chǎn)品,很可能迅速就是上億用戶量。

對B端商家,任何一個(gè)互聯(lián)網(wǎng)巨頭如果打B端市場,憑借巨大的影響力以及合作資源,很可能迅速就可以聚攏數(shù)十萬,乃至上百萬的付費(fèi)B端用戶。

因此,很不幸,接下來的一兩年內(nèi),這套系統(tǒng)將要面臨業(yè)務(wù)的高速增長帶來的巨大技術(shù)挑戰(zhàn)和壓力。

四、海量數(shù)據(jù)存儲和計(jì)算的技術(shù)挑戰(zhàn)

其實(shí)跟很多大型系統(tǒng)遇到的第一個(gè)技術(shù)挑戰(zhàn)一樣,這套系統(tǒng)遇到的第一個(gè)大問題,就是海量數(shù)據(jù)的存儲。

你一個(gè)系統(tǒng)剛開始上線也許就幾十個(gè)商家用,接著隨著你們產(chǎn)品的銷售持續(xù)大力推廣,可能幾個(gè)月內(nèi)就會聚攏起來十萬級別的用戶。

這些用戶每天都會大量的使用你提供的產(chǎn)品,進(jìn)而每天都會產(chǎn)生大量的數(shù)據(jù),大家可以想象一下,在數(shù)十萬規(guī)模的商家用戶使用場景下,每天你新增的數(shù)據(jù)量大概會是幾千萬條數(shù)據(jù),記住,這可是每天新增的數(shù)據(jù)!這將會給上面你看到的那個(gè)很low的架構(gòu)帶來巨大的壓力。

如果你在負(fù)責(zé)上面那套系統(tǒng),結(jié)果慢慢的發(fā)現(xiàn),每天都要涌入MySQL幾千萬條數(shù)據(jù),這種現(xiàn)象是令人感到崩潰的,因?yàn)槟愕腗ySQL中的單表數(shù)據(jù)量會迅速膨脹,很快就會達(dá)到單表幾億條數(shù)據(jù),甚至是數(shù)十億條數(shù)據(jù),然后你對那些怪獸一樣的大表運(yùn)行幾百行乃至上千行的SQL?其中包含了N層嵌套查詢以及N個(gè)各種多表連接?

我跟你打賭,如果你愿意試一下,你會發(fā)現(xiàn)你的數(shù)據(jù)平臺系統(tǒng)直接卡死,因?yàn)橐粋€(gè)大SQL可能都要幾個(gè)小時(shí)才能跑完。然后MySQL的cpu負(fù)載壓力直接100%,弄不好就把MySQL數(shù)據(jù)庫服務(wù)器給搞宕機(jī)了。

所以這就是第一個(gè)技術(shù)挑戰(zhàn),數(shù)據(jù)量越來越大,SQL跑的越來越慢,MySQL服務(wù)器壓力越來越大。

我們當(dāng)時(shí)而言,已經(jīng)看到了業(yè)務(wù)的快速增長,因此絕對要先業(yè)務(wù)一步來重構(gòu)系統(tǒng)架構(gòu),不能讓上述情況發(fā)生,第一次架構(gòu)重構(gòu),勢在必行!

五、離線計(jì)算與實(shí)時(shí)計(jì)算的拆分

其實(shí)在幾年前我們做這個(gè)項(xiàng)目的時(shí)候,大數(shù)據(jù)技術(shù)已經(jīng)在國內(nèi)開始運(yùn)用的不錯(cuò)了,而且尤其在一些大型互聯(lián)網(wǎng)公司內(nèi),我們基本上都運(yùn)用大數(shù)據(jù)技術(shù)支撐過很多生產(chǎn)環(huán)境的項(xiàng)目了,在大數(shù)據(jù)這塊技術(shù)的經(jīng)驗(yàn)積累,也是足夠的。

針對這個(gè)數(shù)據(jù)產(chǎn)品的需求,我們完全可以做到,將昨天以及昨天以前的數(shù)據(jù)都放在大數(shù)據(jù)存儲中,進(jìn)行離線存儲和離線計(jì)算,然后只有今天的數(shù)據(jù)是實(shí)時(shí)的采集的。

因此在這種技術(shù)挑戰(zhàn)下,第一次架構(gòu)重構(gòu)的核心要義,就是將離線計(jì)算與實(shí)時(shí)計(jì)算進(jìn)行拆分。

大家看上面那張圖,新的架構(gòu)之下,分為了離線與實(shí)時(shí)兩條計(jì)算鏈路。

一條是離線計(jì)算鏈路:每天凌晨,我們將業(yè)務(wù)系統(tǒng)MySQL庫中的昨天以前的數(shù)據(jù),作為離線數(shù)據(jù)導(dǎo)入Hadoop HDFS中進(jìn)行離線存儲,然后凌晨就基于Hive / Spark對離線存儲中的數(shù)據(jù)進(jìn)行離線計(jì)算。

在離線計(jì)算鏈路全面采用大數(shù)據(jù)相關(guān)技術(shù)來支撐過后,完美解決了海量數(shù)據(jù)的存儲,哪怕你一天進(jìn)來上億條數(shù)據(jù)都沒事,分布式存儲可以隨時(shí)擴(kuò)容,同時(shí)基于分布式計(jì)算技術(shù)天然適合海量數(shù)據(jù)的離線計(jì)算。

即使是每天凌晨耗費(fèi)幾個(gè)小時(shí)將昨天以前的數(shù)據(jù)完成計(jì)算,這個(gè)也沒事,因?yàn)榱璩恳话闶菦]人看這個(gè)數(shù)據(jù)的,所以主要在人家早上8點(diǎn)上班以前,完成數(shù)據(jù)計(jì)算就可以了。

另外一條是實(shí)時(shí)計(jì)算鏈路:每天零點(diǎn)過后,當(dāng)天最新的數(shù)據(jù)變更,全部還是走之前的老路子,秒級同步業(yè)務(wù)庫的數(shù)據(jù)到數(shù)據(jù)平臺存儲中,接著就是數(shù)據(jù)平臺系統(tǒng)定時(shí)運(yùn)行大量的SQL進(jìn)行計(jì)算。同時(shí)在每天零點(diǎn)的時(shí)候,還會從數(shù)據(jù)平臺的存儲中清理掉昨天的數(shù)據(jù),僅僅保留當(dāng)天一天的數(shù)據(jù)而已。

實(shí)時(shí)計(jì)算鏈路最大的改變,就是僅僅在數(shù)據(jù)平臺的本地存儲中保留當(dāng)天一天的數(shù)據(jù)而已,這樣就大幅度降低了要放在MySQL中的數(shù)據(jù)量了。

舉個(gè)例子:比如一天就幾千萬條數(shù)據(jù)放在MySQL里,那么單表數(shù)據(jù)量被維持在了千萬的級別上,此時(shí)如果對SQL對應(yīng)索引以及優(yōu)化到極致之后,勉強(qiáng)還是可以在幾十秒內(nèi)完成所有報(bào)表的計(jì)算。

六、持續(xù)增長的數(shù)據(jù)量和計(jì)算壓力

但是如果僅僅只是做到上面的架構(gòu),還是只能暫時(shí)性的緩解系統(tǒng)架構(gòu)的壓力,因?yàn)闃I(yè)務(wù)還在加速狂飆,繼續(xù)增長。

你老是期望單日的數(shù)據(jù)量在千萬級別,怎么可能?業(yè)務(wù)是不會給你這個(gè)機(jī)會的。很快就可以預(yù)見到單日數(shù)據(jù)量將會達(dá)到幾億,甚至十億的級別。

如果一旦單日數(shù)據(jù)量達(dá)到了數(shù)十億的級別,單表數(shù)據(jù)量上億,你再怎么優(yōu)化SQL性能,有無法保證100多個(gè)幾百行的復(fù)雜SQL可以快速的運(yùn)行完畢了。

到時(shí)候又會回到最初的問題,SQL計(jì)算過慢會導(dǎo)致數(shù)據(jù)平臺核心系統(tǒng)卡死,甚至給MySQL服務(wù)器過大壓力,CPU 100%負(fù)載后宕機(jī)。

而且此外還有另外一個(gè)問題,那就是單個(gè)MySQL數(shù)據(jù)庫服務(wù)器的存儲容量是有限的,如果一旦單日數(shù)據(jù)量達(dá)到甚至超過了單臺MySQL數(shù)據(jù)庫服務(wù)器的存儲極限,那么此時(shí)也會導(dǎo)致單臺MySQL數(shù)據(jù)庫無法容納所有的數(shù)據(jù)了,這也是一個(gè)很大的問題!

第二次架構(gòu)重構(gòu),勢在必行!

七、大數(shù)據(jù)領(lǐng)域的實(shí)時(shí)計(jì)算技術(shù)的缺陷

在幾年前做這個(gè)項(xiàng)目的背景下,當(dāng)時(shí)可供選擇的大數(shù)據(jù)領(lǐng)域的實(shí)時(shí)計(jì)算技術(shù),主要還是Storm,算是比較成熟的一個(gè)技術(shù),另外就是Spark生態(tài)里的Spark Streaming。當(dāng)時(shí)可沒有什么現(xiàn)在較火的Flink、Druid等技術(shù)。

在仔細(xì)調(diào)研了一番過后發(fā)現(xiàn),根本沒有任何一個(gè)大數(shù)據(jù)領(lǐng)域的實(shí)時(shí)計(jì)算技術(shù)可以支撐這個(gè)需求。

因?yàn)镾torm是不支持SQL的,而且即使勉強(qiáng)你讓他支持了,他的SQL支持也會很弱,完全不可能運(yùn)行幾百行甚至上千行的復(fù)雜SQL在這種流式計(jì)算引擎上的執(zhí)行。

Spark Streaming也是同理,當(dāng)時(shí)功能還是比較弱小的,雖然可以支持簡單SQL的執(zhí)行,但是完全無法支持這種復(fù)雜SQL的精準(zhǔn)運(yùn)算。

因此很不幸的是,在當(dāng)時(shí)的技術(shù)背景下,遇到的這個(gè)實(shí)時(shí)數(shù)據(jù)運(yùn)算的痛點(diǎn),沒有任何開源的技術(shù)是可以解決的。必須得自己根據(jù)業(yè)務(wù)的具體場景,從0開始定制開發(fā)自己的一套數(shù)據(jù)平臺系統(tǒng)架構(gòu)。

八、分庫分表解決數(shù)據(jù)擴(kuò)容問題

首先我們要先解決第一個(gè)痛點(diǎn),就是一旦單臺數(shù)據(jù)庫服務(wù)器無法存儲下當(dāng)日的數(shù)據(jù),該怎么辦?

第一個(gè)首選的方案當(dāng)然就是分庫分表了。我們需要將一個(gè)庫拆分為多庫,不用的庫放在不同的數(shù)據(jù)庫服務(wù)器上,同時(shí)每個(gè)庫里放多張表。

采用這套分庫分表架構(gòu)之后,可以做到每個(gè)數(shù)據(jù)庫服務(wù)器放一部分的數(shù)據(jù),而且隨著數(shù)據(jù)量日益增長,可以不斷地增加更多的數(shù)據(jù)庫服務(wù)器來容納更多的數(shù)據(jù),做到按需擴(kuò)容。

同時(shí),每個(gè)庫里單表分為多表,這樣可以保證單表數(shù)據(jù)量不會太大,控制單表的數(shù)據(jù)量在幾百萬的量級,基本上性能優(yōu)化到極致的SQL語句跑起來效率還是不錯(cuò)的,秒級出結(jié)果是可以做到的。

同樣,給大家來一張圖,大家直觀的感受一下:

九、讀寫分離降低數(shù)據(jù)庫服務(wù)器的負(fù)載

此時(shí)分庫分表之后,又面臨著另外一個(gè)問題,就是現(xiàn)在如果對每個(gè)數(shù)據(jù)庫服務(wù)器又是寫入又是讀取的話,會導(dǎo)致數(shù)據(jù)庫服務(wù)器的CPU負(fù)載和IO負(fù)載非常的高!

為什么這么說呢?因?yàn)樵诖藭r(shí)寫數(shù)據(jù)庫的每秒并發(fā)已經(jīng)達(dá)到幾千了,同時(shí)還頻繁的運(yùn)行那種超大SQL來查詢數(shù)據(jù),數(shù)據(jù)庫服務(wù)器的CPU運(yùn)算會極其的繁忙。

因此我們將MySQL做了讀寫分離的部署,每個(gè)主數(shù)據(jù)庫服務(wù)器都掛了多個(gè)從數(shù)據(jù)庫服務(wù)器,寫只能寫入主庫,查可以從從庫來查。

大家一起來看看下面這張圖:

十、自研的滑動(dòng)窗口動(dòng)態(tài)計(jì)算引擎

但是光是做到這一點(diǎn)還是不夠的,因?yàn)槠鋵?shí)在生產(chǎn)環(huán)境發(fā)現(xiàn),哪怕單表數(shù)據(jù)量限制在了幾百萬的級別,你運(yùn)行幾百個(gè)幾百行復(fù)雜SQL,也要幾十秒甚至幾分鐘的時(shí)間,這個(gè)時(shí)效性對付費(fèi)級的產(chǎn)品已經(jīng)有點(diǎn)無法接受,產(chǎn)品提出的極致性能要求是,秒級!

因此對上述系統(tǒng)架構(gòu),我們再次做了架構(gòu)的優(yōu)化,在數(shù)據(jù)平臺中嵌入了自己純自研的滑動(dòng)窗口計(jì)算引擎,核心思想如下:

  • 在數(shù)據(jù)庫binlog采集中間件采集的過程中,要將數(shù)據(jù)的變更切割為一個(gè)一個(gè)的滑動(dòng)時(shí)間窗口,每個(gè)滑動(dòng)時(shí)間窗口為幾秒鐘,對每個(gè)窗口內(nèi)的數(shù)據(jù)打上那個(gè)窗口的標(biāo)簽。
  • 同時(shí)需要維護(hù)一份滑動(dòng)時(shí)間窗口的索引數(shù)據(jù),包括每個(gè)分片的數(shù)據(jù)在哪個(gè)窗口里,每個(gè)窗口的數(shù)據(jù)的一些具體的索引信息和狀態(tài)。
  • 接著數(shù)據(jù)平臺中的核心計(jì)算引擎,不再是每隔幾十秒就運(yùn)行大量SQL對當(dāng)天所有的數(shù)據(jù)全部計(jì)算一遍了,而是對一個(gè)接一個(gè)的滑動(dòng)時(shí)間窗口,根據(jù)窗口標(biāo)簽提取出那個(gè)窗口內(nèi)的數(shù)據(jù)進(jìn)行計(jì)算,計(jì)算的僅僅是最近一個(gè)滑動(dòng)時(shí)間窗口內(nèi)的數(shù)據(jù)。
  • 接著對這個(gè)滑動(dòng)時(shí)間窗口內(nèi)的數(shù)據(jù),可能最多就千條左右吧,運(yùn)行所有的復(fù)雜SQL計(jì)算出這個(gè)滑動(dòng)時(shí)間窗口內(nèi)的報(bào)表數(shù)據(jù),然后將這個(gè)窗口數(shù)據(jù)計(jì)算出的結(jié)果,與之前計(jì)算出來的其他窗口內(nèi)的計(jì)算結(jié)果進(jìn)行合并,最后放入MySQL中的報(bào)表內(nèi)。
  • 此外,這里需要考慮到一系列的生產(chǎn)級機(jī)制,包括滑動(dòng)時(shí)間窗口如果計(jì)算失敗怎么辦?如果一個(gè)滑動(dòng)時(shí)間窗口計(jì)算過慢怎么辦?滑動(dòng)窗口計(jì)算過程中系統(tǒng)宕機(jī)了如何在重啟之后自動(dòng)恢復(fù)計(jì)算?等等。

通過這套滑動(dòng)窗口的計(jì)算引擎,我們直接將系統(tǒng)計(jì)算性能提升了幾十倍,基本上每個(gè)滑動(dòng)窗口的數(shù)據(jù)只要幾秒鐘就可以完成全部報(bào)表的計(jì)算,相當(dāng)于一下子把最終呈現(xiàn)給用戶的實(shí)時(shí)數(shù)據(jù)的時(shí)效性提升到了幾秒鐘,而不是幾十秒。

同樣,大家看看下面的圖。

十一、離線計(jì)算鏈路的性能優(yōu)化

實(shí)時(shí)計(jì)算鏈路的性能問題通過自研滑動(dòng)窗口計(jì)算引擎來解決了,但是離線計(jì)算鏈路此時(shí)又出現(xiàn)了性能問題。

因?yàn)槊刻炝璩繌臉I(yè)務(wù)庫中離線導(dǎo)入的是歷史全量數(shù)據(jù),接著需要在凌晨針對百億量級的全量數(shù)據(jù),運(yùn)行很多復(fù)雜的上千行復(fù)雜SQL來進(jìn)行運(yùn)算,當(dāng)數(shù)據(jù)量達(dá)到百億之后,這個(gè)過程耗時(shí)很長,有時(shí)候要從凌晨一直計(jì)算到上午。

關(guān)鍵問題就在于,離線計(jì)算鏈路,每天都是導(dǎo)入全量數(shù)據(jù)來進(jìn)行計(jì)算,這就很坑了。

之所以這么做,是因?yàn)閺臉I(yè)務(wù)庫同步數(shù)據(jù)時(shí),每天都涉及到數(shù)據(jù)的更新操作,而hadoop里的數(shù)據(jù)是沒法跟業(yè)務(wù)庫那樣來進(jìn)行更新的,因此最開始都是每天導(dǎo)入全量歷史數(shù)據(jù),作為一個(gè)最新快照來進(jìn)行全量計(jì)算。

在這里,我們對離線計(jì)算鏈路進(jìn)行了優(yōu)化,主要就是全量計(jì)算轉(zhuǎn)增量計(jì)算:每天數(shù)據(jù)在導(dǎo)入hadoop之后,都會針對數(shù)據(jù)的業(yè)務(wù)時(shí)間戳來分析和提取出來每天變更過的增量數(shù)據(jù),將這些增量數(shù)據(jù)放入獨(dú)立的增量數(shù)據(jù)表中。

同時(shí)需要根據(jù)具體的業(yè)務(wù)需求,自動(dòng)分析數(shù)據(jù)計(jì)算的基礎(chǔ)血緣關(guān)系,有可能增量數(shù)據(jù)需要與部分全量數(shù)據(jù)混合才能完成計(jì)算,此時(shí)可能會提取部分全量歷史數(shù)據(jù),合并完成計(jì)算。計(jì)算完成之后,將計(jì)算結(jié)果與歷史計(jì)算結(jié)果進(jìn)行合并。

在完成這個(gè)全量計(jì)算轉(zhuǎn)增量計(jì)算的過程之后,離線計(jì)算鏈路在凌晨基本上百億級別的數(shù)據(jù)量,只要對昨天的增量數(shù)據(jù)花費(fèi)一兩個(gè)小時(shí)完成計(jì)算之后,就可以完成離線計(jì)算的全部任務(wù),性能相較于全量計(jì)算提升至少十倍以上。

十二、階段性總結(jié)

到此為止,就是這套系統(tǒng)在最初一段時(shí)間做出來的一套架構(gòu),不算太復(fù)雜,還有很多缺陷,不完美,但是在當(dāng)時(shí)的業(yè)務(wù)背景下效果相當(dāng)?shù)牟诲e(cuò)。

在這套架構(gòu)對應(yīng)的早期業(yè)務(wù)背景下,每天新增數(shù)據(jù)大概是億級左右,但是分庫分表之后,單表數(shù)據(jù)量在百萬級別,單臺數(shù)據(jù)庫服務(wù)器的高峰期寫入壓力在2000/s,查詢壓力在100/s,數(shù)據(jù)庫集群承載的總高峰寫入壓力在1萬/s,查詢壓力在500/s,有需要還可以隨時(shí)擴(kuò)容更多的數(shù)據(jù)庫服務(wù)器,承載更多的數(shù)據(jù)量,更高的寫入并發(fā)與查詢并發(fā)。

而且,因?yàn)樽隽俗x寫分離,因此每個(gè)數(shù)據(jù)庫服務(wù)器的CPU負(fù)載和IO負(fù)載都不會在高峰期打滿,避免數(shù)據(jù)庫服務(wù)器的負(fù)載過高。

而基于滑動(dòng)時(shí)間窗口的自研計(jì)算引擎,可以保證當(dāng)天更新的實(shí)時(shí)數(shù)據(jù)主要幾秒鐘就可以完成一個(gè)微批次的計(jì)算,反饋到用戶看到的數(shù)據(jù)報(bào)表中。

同時(shí)這套引擎自行管理著計(jì)算的狀態(tài)與日志,如果出現(xiàn)某個(gè)窗口的計(jì)算失敗、系統(tǒng)宕機(jī)、計(jì)算超時(shí),等各種異常的情況,這個(gè)套引擎可以自動(dòng)重試與恢復(fù)。

此外,昨天以前的海量數(shù)據(jù)都是走Hadoop與Spark生態(tài)的離線存儲與計(jì)算。經(jīng)過性能優(yōu)化之后,每天凌晨花費(fèi)一兩個(gè)小時(shí),算好昨天以前所有的數(shù)據(jù)即可。

最后實(shí)時(shí)與離線的計(jì)算結(jié)果在同一個(gè)MySQL數(shù)據(jù)庫中融合,此時(shí)用戶如果對業(yè)務(wù)系統(tǒng)做出操作,實(shí)時(shí)數(shù)據(jù)報(bào)表在幾秒后就會刷新,如果要看昨天以前的數(shù)據(jù)可以隨時(shí)選擇時(shí)間范圍查看即可,暫時(shí)性是滿足了業(yè)務(wù)的需求。

早期的幾個(gè)月里,日增上億數(shù)據(jù),離線與實(shí)時(shí)兩條鏈路中的整體數(shù)據(jù)量級達(dá)到了百億級別,無論是存儲擴(kuò)容,還是高效計(jì)算,這套架構(gòu)基本是撐住了。

十三、下一階段的展望

這個(gè)大型系統(tǒng)架構(gòu)演進(jìn)實(shí)踐是一個(gè)系列的文章,將會包含很多篇文章,因?yàn)橐粋€(gè)大型的系統(tǒng)架構(gòu)演進(jìn)的過程,會持續(xù)很長時(shí)間,做出很多次的架構(gòu)升級與重構(gòu),不斷的解決日益增長的技術(shù)挑戰(zhàn),最終完美的抗住海量數(shù)據(jù)、高并發(fā)、高性能、高可用等場景。

下一篇文章會說說下一步是如何將數(shù)據(jù)平臺系統(tǒng)重構(gòu)為一套高可用高容錯(cuò)的分布式系統(tǒng)架構(gòu)的,來解決單點(diǎn)故障、單系統(tǒng)CPU負(fù)載過高、自動(dòng)故障轉(zhuǎn)移、自動(dòng)數(shù)據(jù)容錯(cuò)等相關(guān)的問題。包括之后還會有多篇文章涉及到我們自研的更加復(fù)雜的支撐高并發(fā)、高可用、高性能、海量數(shù)據(jù)的平臺架構(gòu)。

十四、上篇文章的答疑

之前發(fā)布過一篇文章,寫了一個(gè)分布式鎖的高并發(fā)優(yōu)化的文章,具體參見:??為什么公司規(guī)定所有接口都必須加上分布式鎖,你知道嗎???收到了大家很多的提問,其實(shí)最終都是一個(gè)問題:

針對那篇文章里的用分布式鎖的分段加鎖的方式,解決庫存超賣問題,那如果一個(gè)分段的庫存不滿足要購買的數(shù)量,怎么辦?

第一,我當(dāng)時(shí)文章里提了一句,可能沒寫太詳細(xì),如果一個(gè)分段庫存不足,要鎖其他的分段,進(jìn)行合并扣減,如果你做分段加鎖,那就是這樣的,很麻煩。

如果大家去看看Java 8里的LongAdder的源碼,他的分段加鎖的優(yōu)化,也是如此的麻煩,要做段遷移。

第二,我在那篇文章里反復(fù)強(qiáng)調(diào)了一下,不要對號入座,因?yàn)閷?shí)際的電商庫存超賣問題,有很多其他的技術(shù)手段,我們就用的是其他的方案,不是這個(gè)方案,以后有機(jī)會給大家專門講如何解決電商庫存超賣問題。

那篇文章僅僅是用那個(gè)例作為一個(gè)業(yè)務(wù)案例而已,闡述一下分布式鎖的并發(fā)問題,以及高并發(fā)的優(yōu)化手段,方便大家來理解那個(gè)意思,僅此而已。

第三,最后再強(qiáng)調(diào)一下,大家關(guān)注分段加鎖的思想就好,切記不要對號入座,不要關(guān)注過多在庫存超賣業(yè)務(wù)上了。

責(zé)任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2020-03-23 13:40:48

GitHub代碼開發(fā)者

2017-02-27 11:06:28

Github開源項(xiàng)目

2019-01-22 15:37:01

GitHub代碼開發(fā)者

2022-01-10 16:25:18

GitHub語言開源

2021-05-26 09:35:22

Github開源項(xiàng)目

2019-08-13 09:45:45

GitHubJavaScript開發(fā)者

2023-05-16 08:47:39

2014-09-10 10:14:14

2023-05-03 21:42:02

Github開源項(xiàng)目

2020-11-09 14:26:30

GitHub 技術(shù)開源

2021-01-05 10:27:02

GithubPython開源項(xiàng)目

2019-05-29 13:59:03

GitHub開源搜索功能

2020-05-15 09:50:08

GitHub開源項(xiàng)目

2018-12-19 15:15:24

開源Github

2011-07-08 15:22:29

英特爾云計(jì)算

2021-01-26 09:30:44

GitHub開源項(xiàng)目

2021-06-29 05:18:06

Windows 11操作系統(tǒng)微軟

2021-07-06 09:28:35

GitHub開發(fā)者開源

2022-02-14 20:53:33

開源庫開發(fā)代碼

2015-10-10 14:44:55

Github提高水平
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號