數(shù)據(jù)批處理速度慢?不妨試試這個(gè)

業(yè)務(wù)系統(tǒng)產(chǎn)生的明細(xì)數(shù)據(jù)通常要經(jīng)過加工處理,按照一定邏輯計(jì)算成需要的結(jié)果,用以支持企業(yè)的經(jīng)營活動(dòng)。這類數(shù)據(jù)加工任務(wù)一般會(huì)有很多個(gè),需要批量完成計(jì)算,在銀行和保險(xiǎn)行業(yè)常常被稱為跑批,其它像石油、電力等行業(yè)也經(jīng)常會(huì)有跑批的需求。

大部分業(yè)務(wù)統(tǒng)計(jì)都會(huì)要求以某日作為截止點(diǎn),而且為了不影響生產(chǎn)系統(tǒng)的運(yùn)行,跑批任務(wù)一般會(huì)在夜間進(jìn)行,這時(shí)候才能將生產(chǎn)系統(tǒng)當(dāng)天產(chǎn)生的新明細(xì)數(shù)據(jù)導(dǎo)出來,送到專門的數(shù)據(jù)庫或數(shù)據(jù)倉庫完成跑批計(jì)算。第二天早上,跑批結(jié)果就可以提供給業(yè)務(wù)人員使用了。

和在線查詢不同,跑批計(jì)算是定時(shí)自動(dòng)執(zhí)行的離線任務(wù),不會(huì)出現(xiàn)多人同時(shí)訪問一個(gè)任務(wù)的情況,所以沒有并發(fā)問題,也不必實(shí)時(shí)返回結(jié)果。但是,跑批必須在規(guī)定的窗口時(shí)間內(nèi)完成。比如某銀行的跑批窗口時(shí)間是晚上8:00到第二天早上7:00,如果到了早上7:00跑批任務(wù)還沒有完成,就會(huì)造成業(yè)務(wù)人員無法正常工作的嚴(yán)重后果。

跑批任務(wù)涉及的數(shù)據(jù)量非常大,很可能用到所有的歷史數(shù)據(jù),而且計(jì)算邏輯復(fù)雜、步驟眾多,所以跑批時(shí)間經(jīng)常是以小時(shí)計(jì)的,一個(gè)任務(wù)兩三小時(shí)是家常便飯,跑到十個(gè)小時(shí)也不足為奇。隨著業(yè)務(wù)的發(fā)展,數(shù)據(jù)量還在不斷增加。跑批數(shù)據(jù)庫的負(fù)擔(dān)快速增長,就會(huì)發(fā)生整晚都跑不完的情況,嚴(yán)重影響用戶的業(yè)務(wù),這是無法接受的。

問題分析

要解決跑批時(shí)間過長的問題,必須仔細(xì)分析現(xiàn)有的系統(tǒng)架構(gòu)中的問題。

跑批系統(tǒng)比較典型的架構(gòu)大致如下圖:

從圖上看,數(shù)據(jù)要從生產(chǎn)數(shù)據(jù)庫取出,存入跑批數(shù)據(jù)庫。跑批數(shù)據(jù)庫通常是關(guān)系型的,編寫存儲(chǔ)過程代碼完成跑批計(jì)算。跑批的結(jié)果一般不會(huì)直接使用,而是再從跑批數(shù)據(jù)庫中導(dǎo)出,采用接口文件的方式提供給其他系統(tǒng),或者再導(dǎo)入其他系統(tǒng)數(shù)據(jù)庫。這是比較典型的架構(gòu),圖中的生產(chǎn)數(shù)據(jù)庫也可能是某個(gè)中央數(shù)據(jù)倉庫或者Hadoop等。一般情況下,生產(chǎn)庫和跑批庫不會(huì)是同一種數(shù)據(jù)庫,它們之間往往通過文件的方式傳遞數(shù)據(jù),這樣也比較有利于降低耦合度。跑批計(jì)算完成后,結(jié)果要給多個(gè)應(yīng)用系統(tǒng)使用,一般也都是以文件方式傳遞。

跑批很慢的第一個(gè)原因,是用來完成跑批任務(wù)的關(guān)系數(shù)據(jù)庫入庫、出庫太慢。由于關(guān)系數(shù)據(jù)庫的存儲(chǔ)和計(jì)算能力具有封閉性,數(shù)據(jù)的進(jìn)出要做過多的約束檢查和安全處理,當(dāng)數(shù)據(jù)量較大時(shí),寫入讀出的效率非常低,耗時(shí)會(huì)非常長。所以,跑批數(shù)據(jù)庫導(dǎo)入文件數(shù)據(jù)的過程,以及跑批計(jì)算結(jié)果再導(dǎo)出文件的過程都會(huì)很慢。

跑批很慢的第二個(gè)原因,是存儲(chǔ)過程性能差。由于SQL的語法體系過于陳舊,存在諸多限制,很多高效的算法無法實(shí)施,所以存儲(chǔ)過程中的SQL語句計(jì)算性能很不理想。而且,業(yè)務(wù)邏輯比較復(fù)雜的時(shí)候很難用一個(gè)SQL實(shí)現(xiàn),經(jīng)常要分成多個(gè)步驟,用十幾甚至幾十個(gè)SQL語句才能完成。每個(gè)SQL的中間結(jié)果,都要存入臨時(shí)表給后續(xù)步驟的SQL使用。臨時(shí)表數(shù)據(jù)量較大時(shí)就必須落地,會(huì)造成大量的數(shù)據(jù)寫出。而數(shù)據(jù)庫的寫出要比讀入性能差很多,會(huì)嚴(yán)重拖慢整個(gè)存儲(chǔ)過程。

對于更復(fù)雜的計(jì)算,甚至很難用SQL語句直接實(shí)現(xiàn),需要用數(shù)據(jù)庫游標(biāo)遍歷取出數(shù)據(jù),循環(huán)計(jì)算。但數(shù)據(jù)庫游標(biāo)遍歷計(jì)算性能又要比SQL語句差很多,一般也都不直接支持多線程并行計(jì)算,很難利用多CPU核的計(jì)算能力,會(huì)讓計(jì)算性能更加糟糕。

那么,是否可以考慮用分布式數(shù)據(jù)庫來代替?zhèn)鹘y(tǒng)關(guān)系數(shù)據(jù)庫,通過增加節(jié)點(diǎn)數(shù)量的辦法,來提高跑批任務(wù)的速度呢?

答案仍然是不可行。主要原因是跑批計(jì)算的邏輯相當(dāng)復(fù)雜,即使是用傳統(tǒng)數(shù)據(jù)庫的存儲(chǔ)過程,也常常要寫幾千甚至上萬行代碼,而分布式數(shù)據(jù)庫的存儲(chǔ)過程計(jì)算能力還比較弱,很難實(shí)現(xiàn)這么復(fù)雜的跑批計(jì)算。

而且,當(dāng)復(fù)雜計(jì)算任務(wù)不得不分成多個(gè)步驟時(shí),分布式數(shù)據(jù)庫也面臨中間結(jié)果落地的問題。由于數(shù)據(jù)可能在不同的節(jié)點(diǎn)上,所以前序步驟將中間結(jié)果落地,后續(xù)步驟再讀取的時(shí)候,都會(huì)造成大量跨網(wǎng)絡(luò)的讀寫操作,性能很不可控。

這時(shí),也不能采用分布式數(shù)據(jù)庫依靠數(shù)據(jù)冗余來提升查詢速度的辦法。這是因?yàn)椋樵冎翱梢灶A(yù)先準(zhǔn)備好多份冗余數(shù)據(jù),但是,跑批的中間結(jié)果是臨時(shí)生成的,如果冗余的話就要臨時(shí)生成多份,整體的性能只會(huì)變得更慢。

所以,現(xiàn)實(shí)的跑批業(yè)務(wù)通常仍然是使用大型單體數(shù)據(jù)庫進(jìn)行,計(jì)算強(qiáng)度太大時(shí)會(huì)采用類似ExaData這樣的一體機(jī)(ExaData是多數(shù)據(jù)庫,但被Oracle專門優(yōu)化過,可以看成是個(gè)超大型單體數(shù)據(jù)庫)。雖然很慢,但是暫時(shí)找不到更好的選擇,只有這類大型數(shù)據(jù)庫有足夠的計(jì)算能力,所以只能用它來完成跑批任務(wù)了。

SPL用于跑批

開源的專業(yè)計(jì)算引擎SPL提供了不依賴數(shù)據(jù)庫的計(jì)算能力,直接利用文件系統(tǒng)計(jì)算,可以解決關(guān)系數(shù)據(jù)庫出庫入庫太慢的問題。而且SPL實(shí)現(xiàn)了更優(yōu)算法,性能遠(yuǎn)遠(yuǎn)超過存儲(chǔ)過程,能顯著提高單機(jī)計(jì)算效率,非常適合跑批計(jì)算。

利用SPL實(shí)現(xiàn)的跑批系統(tǒng)新架構(gòu)是下面這樣的:

在新架構(gòu)中,SPL解決了造成跑批慢的兩大瓶頸問題。

首先來看數(shù)據(jù)的入庫、出庫問題。SPL可以直接基于生產(chǎn)庫導(dǎo)出的文件計(jì)算,不必再將數(shù)據(jù)導(dǎo)入到關(guān)系數(shù)據(jù)庫中。完成跑批計(jì)算后,SPL還能將最終結(jié)果直接存儲(chǔ)成文本文件等通用格式,傳遞給其他應(yīng)用系統(tǒng),避免了原有跑批數(shù)據(jù)庫的出庫操作。這樣一來,SPL就省去了關(guān)系數(shù)據(jù)庫緩慢的入庫、出庫過程。

下面再來看計(jì)算的過程。SPL提供了更優(yōu)的算法(有許多是業(yè)界首創(chuàng)),計(jì)算性能遠(yuǎn)遠(yuǎn)超過存儲(chǔ)過程和SQL語句。這些高性能算法包括:

這些高性能算法可以應(yīng)用于跑批任務(wù)中的常見JOIN計(jì)算、遍歷、分組匯總等,能有效提升計(jì)算速度。例如,跑批任務(wù)常常要遍歷整個(gè)歷史表。有些情況下,對一個(gè)歷史表還要遍歷好多次,來完成多種業(yè)務(wù)邏輯的計(jì)算。歷史表數(shù)據(jù)量一般都很大,每次遍歷都要消耗很多的時(shí)間。此時(shí)我們可以應(yīng)用SPL的遍歷復(fù)用機(jī)制,僅對大表遍歷一次,就可以同時(shí)完成多種計(jì)算,可以節(jié)省大量時(shí)間。

SPL的多路游標(biāo)能做到數(shù)據(jù)的并行讀取和計(jì)算,即使是很復(fù)雜的跑批邏輯,也可以利用多CPU核實(shí)現(xiàn)多線程并行運(yùn)算。而數(shù)據(jù)庫游標(biāo)是很難并行的,這樣一來,SPL的計(jì)算速度常常可以達(dá)到存儲(chǔ)過程的數(shù)倍。

SPL的延遲游標(biāo)機(jī)制,可以在一個(gè)游標(biāo)上定義多個(gè)計(jì)算步驟,之后讓數(shù)據(jù)流按順序依次完成這些步驟,實(shí)現(xiàn)鏈?zhǔn)接?jì)算,能夠有效減少中間結(jié)果落地的次數(shù)。在數(shù)據(jù)必須落地的情況下,SPL也可以將中間結(jié)果存成內(nèi)置的高性能數(shù)據(jù)格式,供下一個(gè)步驟使用。SPL高性能存儲(chǔ)基于文件,采用有序壓縮存儲(chǔ)、自由列式存儲(chǔ)、倍增分段、自有壓縮編碼等技術(shù),減少了硬盤占用,讀寫速度要遠(yuǎn)遠(yuǎn)好于數(shù)據(jù)庫。

應(yīng)用效果

SPL在技術(shù)架構(gòu)上打破了關(guān)系型跑批數(shù)據(jù)庫存在的兩大瓶頸,在實(shí)際應(yīng)用中也取得了非常好的效果。

L 銀行跑批任務(wù)采用傳統(tǒng)架構(gòu),以關(guān)系數(shù)據(jù)庫作為跑批數(shù)據(jù)庫,用存儲(chǔ)過程編程實(shí)現(xiàn)跑批邏輯。其中,貸款協(xié)議存儲(chǔ)過程需要執(zhí)行 2 個(gè)小時(shí),而且是很多其他跑批任務(wù)的前序任務(wù),耗時(shí)這么久,對整個(gè)跑批任務(wù)造成了嚴(yán)重影響。

采用SPL后,使用高性能列存、文件游標(biāo)、多線程并行、小結(jié)果內(nèi)存分組、游標(biāo)復(fù)用等高性能算法和存儲(chǔ)機(jī)制,將原來2個(gè)小時(shí)的計(jì)算時(shí)間縮短為10分鐘,性能提高12倍

而且,SPL代碼更簡潔。原存儲(chǔ)過程3300多行,改為SPL后,僅有500格語句,代碼量減少了6倍多,大大提高了開發(fā)效率。

P保險(xiǎn)公司的車險(xiǎn)業(yè)務(wù)中,需要用往年歷史保單來關(guān)聯(lián)新的保單,在跑批中稱為歷史保單關(guān)聯(lián)任務(wù)。原來也采用關(guān)系數(shù)據(jù)庫完成跑批,存儲(chǔ)過程計(jì)算10天的新增保單關(guān)聯(lián)歷史保單,運(yùn)行時(shí)間47分鐘;30天則需要112分鐘,接近2小時(shí);如果日期跨度更大,運(yùn)行時(shí)間就會(huì)長的無法忍受,基本就變成不可能完成的任務(wù)了。

采用SPL后,應(yīng)用了高性能文件存儲(chǔ)、文件游標(biāo)、有序歸并分段取出、內(nèi)存關(guān)聯(lián)遍歷復(fù)用等技術(shù),計(jì)算10天新增保單僅需13分鐘;30天新增保單只需要17分鐘,速度提高了近7倍。而且,新算法執(zhí)行的時(shí)間隨著保單天數(shù)的增長并不是很大,并沒有像存儲(chǔ)過程那樣成正比的增長。

從代碼總量來看,原來存儲(chǔ)過程有2000行代碼,去掉注釋后還有1800多行,而SPL的全部代碼只有不到500格,不到原來的1/3

T銀行通過互聯(lián)網(wǎng)渠道發(fā)放貸款的明細(xì)數(shù)據(jù),需要每天執(zhí)行跑批任務(wù),統(tǒng)計(jì)匯總指定日期之前的所有歷史數(shù)據(jù)。跑批任務(wù)采用關(guān)系數(shù)據(jù)庫的SQL語句實(shí)現(xiàn),運(yùn)行總時(shí)間7.8小時(shí),占用了過多的跑批時(shí)間,甚至影響了其他的跑批任務(wù),必須優(yōu)化。

采用SPL后,應(yīng)用了高性能文件、文件游標(biāo)、有序分組、有序關(guān)聯(lián)、延遲游標(biāo)、二分法等技術(shù),原來需要7.8小時(shí)的跑批任務(wù),單線程僅需180秒,2線程僅需137秒,速度提高了204倍

SPL資料

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,345評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,494評論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,283評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,953評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,714評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,186評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,410評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,940評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,776評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,976評論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,210評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,654評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,958評論 2 373

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