摘要:?對(duì)于阿里云大數(shù)據(jù)數(shù)倉建設(shè)性能優(yōu)化而言,主要可以從調(diào)度優(yōu)化、模型優(yōu)化、同步優(yōu)化以及任務(wù)優(yōu)化這四個(gè)方面著手。其實(shí),對(duì)于性能優(yōu)化而言,最終還是會(huì)歸結(jié)到“資源”之上,所以資源是否足夠,分配是否合理也是我們?cè)谶M(jìn)行性能優(yōu)化時(shí)必須考慮的關(guān)鍵所在。
摘要:對(duì)于阿里云大數(shù)據(jù)數(shù)倉建設(shè)性能優(yōu)化而言,主要可以從調(diào)度優(yōu)化、模型優(yōu)化、同步優(yōu)化以及任務(wù)優(yōu)化這四個(gè)方面著手。其實(shí),對(duì)于性能優(yōu)化而言,最終還是會(huì)歸結(jié)到“資源”之上,所以資源是否足夠,分配是否合理也是我們?cè)谶M(jìn)行性能優(yōu)化時(shí)必須考慮的關(guān)鍵所在。
以下內(nèi)容根據(jù)演講視頻以及PPT整理而成。
本次演講視頻分享,請(qǐng)戳這里!
本次演講PPT下載,請(qǐng)戳這里!
關(guān)于MaxCompute更多精彩文章,請(qǐng)移步云棲社區(qū)MaxCompute公眾號(hào)!
本文將主要圍繞以下四個(gè)方面進(jìn)行介紹:調(diào)度優(yōu)化、模型優(yōu)化、同步優(yōu)化以及任務(wù)優(yōu)化。對(duì)于調(diào)度優(yōu)化而言,將分享任務(wù)調(diào)度如何進(jìn)行優(yōu)化,以及如何看到調(diào)度的瓶頸點(diǎn),以及在初步進(jìn)行建設(shè)和使用數(shù)據(jù)倉庫的任務(wù)之后,對(duì)于任務(wù)如何進(jìn)行調(diào)整來滿足業(yè)務(wù)的時(shí)間要求。對(duì)于模型優(yōu)化而言,主要包括一些優(yōu)化相關(guān)的想法、建議以及技術(shù)的優(yōu)化點(diǎn)。對(duì)于數(shù)據(jù)同步優(yōu)化而言,也是大家在建設(shè)數(shù)據(jù)倉庫的過程中經(jīng)常遇到的問題,也就是將數(shù)據(jù)從其他數(shù)據(jù)庫同步過來或者向其他數(shù)據(jù)庫進(jìn)行數(shù)據(jù)同步的時(shí)候,經(jīng)常會(huì)遇到一些像某些任務(wù)運(yùn)行過慢或者影響其他任務(wù)的情況。對(duì)于任務(wù)優(yōu)化而言,主要指的是計(jì)算任務(wù),也可以理解為MaxCompute的SQL任務(wù),這部分將與大家分享如何去優(yōu)化這部分的任務(wù)。
一、調(diào)度優(yōu)化
在數(shù)據(jù)倉庫建設(shè)的過程中,大家都會(huì)需要跑一些任務(wù),那么這些任務(wù)如何進(jìn)行配置才會(huì)是最優(yōu)的呢?如果出現(xiàn)了瓶頸點(diǎn)或者業(yè)務(wù)第二天所需要的數(shù)據(jù)并沒有給到,那么很大一部分的情況需要從調(diào)度方面來考慮,是不是有些任務(wù)的時(shí)間點(diǎn)設(shè)置的不合理?或者是不是有些任務(wù)的優(yōu)先級(jí)設(shè)置的不合理?這些可能是在調(diào)度層面,大家需要優(yōu)先考慮的一個(gè)點(diǎn)。
調(diào)度優(yōu)化方式
調(diào)度優(yōu)化的主要方式如下圖所示,按照道理前三點(diǎn)應(yīng)該在設(shè)計(jì)初期提前想到或者提前規(guī)劃好的。而目前大部分客戶還是用了一段時(shí)間的數(shù)據(jù)倉庫的時(shí)候,才發(fā)現(xiàn)存在一些問題,當(dāng)?shù)诙煨枰鰣?bào)表的時(shí)候才想到去優(yōu)化這些點(diǎn)。
第一點(diǎn)就是對(duì)于大任務(wù)而言,需要將其預(yù)定處理的時(shí)間提前,這里的大任務(wù)也就是耗時(shí)比較長(zhǎng)的任務(wù),如果任務(wù)已經(jīng)在跑了,那么很好評(píng)估,在DataWorks里面可以看到哪些任務(wù)跑得慢。此外還有一個(gè)評(píng)估方法就是在第一次建立數(shù)倉的時(shí)候,表的數(shù)據(jù)量很大那么也肯定是大任務(wù)。對(duì)于這些大任務(wù)而言,需要將其定時(shí)的時(shí)間提前,也就是將其優(yōu)先級(jí)提前。第二點(diǎn)就是將關(guān)鍵節(jié)點(diǎn)的定時(shí)時(shí)間提前,這里所謂的關(guān)鍵節(jié)點(diǎn)并不是說其數(shù)據(jù)量大,而是業(yè)務(wù)很重要的任務(wù)。第三點(diǎn)就是需要做到任務(wù)的隔離,這里主要指的是在使用DataWorks的時(shí)候會(huì)用到一些調(diào)度資源,不管是運(yùn)行SQL也好還是運(yùn)行同步任務(wù)也好,這些任務(wù)都需要跑在DataWorks的調(diào)度資源里面,那么如果將這些任務(wù)都放在一個(gè)項(xiàng)目就會(huì)出現(xiàn)問題,比如某個(gè)同步任務(wù)設(shè)置了10個(gè)并發(fā),這樣就占據(jù)了10多個(gè)調(diào)度資源,這樣就可能將資源全部占滿了,這樣就會(huì)導(dǎo)致其他任務(wù)需要等待,這里不是指的MaxCompute資源不夠,而是DataWorks的調(diào)度資源不夠了。因此,一方面需要將開發(fā)和生產(chǎn)隔離開,避免因?yàn)殚_發(fā)臨時(shí)啟動(dòng)了測(cè)試任務(wù)導(dǎo)致生產(chǎn)環(huán)境受到影響,因此要盡量將DataWorks里面的開發(fā)項(xiàng)目和生產(chǎn)項(xiàng)目分離開。此外,如果生產(chǎn)項(xiàng)目也很大,可能就需要按照數(shù)倉的分層或者不同業(yè)務(wù)拆分成不同的項(xiàng)目,這也是避免資源出現(xiàn)搶占,避免影響其他業(yè)務(wù)的一種方式。當(dāng)然,這樣的做法有利也有弊,因?yàn)檫@樣做會(huì)使得復(fù)雜度增加,對(duì)于企業(yè)而言,后續(xù)的運(yùn)維成本也會(huì)高一些,因此這需要看大家應(yīng)該如何評(píng)估,如果數(shù)據(jù)量達(dá)到了一定的規(guī)模其實(shí)可以分拆出來的,但是如果數(shù)據(jù)量不是很大,那么就可以先不考慮分拆。第四點(diǎn)就是減少任務(wù)層級(jí)的依賴,大家在進(jìn)行調(diào)度的時(shí)候,都會(huì)在DataWorks里面看到依賴的上一層或者下游依賴哪一些任務(wù),而任務(wù)互相依賴的層級(jí)應(yīng)該是越少越好的,但是按照數(shù)倉分層,依賴至少需要三層,這三層依賴是肯定存在的,除此之外還會(huì)有一些中間表,這樣就會(huì)有四層或者五層,但是盡量不要出現(xiàn)10層以上甚至20層的依賴,這樣復(fù)雜的任務(wù)依賴會(huì)使得后期去排查任務(wù)的依賴成本升高。如果在數(shù)倉建設(shè)的初期或者建設(shè)的過程中發(fā)現(xiàn)了一些問題就可以從以上四個(gè)點(diǎn)出發(fā)進(jìn)行考慮。
二、模型優(yōu)化
對(duì)于模型優(yōu)化而言,必須要按照什么方式進(jìn)行設(shè)計(jì)以及模型必須是什么樣子的,其實(shí)沒有一個(gè)定性的結(jié)論。這里也只是給出一些建議和想法。
對(duì)于數(shù)倉的建模而言,其實(shí)可以分為3NF建模和維度建模等,而推薦使用維度建模方式,可以按照星型模型或者雪花型架構(gòu)的方式去建模。3NF建模方式或者實(shí)體建模方式的應(yīng)用型會(huì)差一點(diǎn),在很多時(shí)候其性能也會(huì)差一點(diǎn),但是3NF在很多時(shí)候都會(huì)避免數(shù)據(jù)的冗余,其擴(kuò)展性會(huì)好一些。而維度建模會(huì)有一定的數(shù)據(jù)冗余,并且冗余程度會(huì)很高,但是對(duì)于上層使用者而言,其易用性要好很多,并且其查詢的性能也會(huì)好很多,雖然可擴(kuò)展性會(huì)稍微差一些,但是仍然處于可接受的范圍之內(nèi)。之所以在MaxCompute這邊推薦大家使用維度建模,是因?yàn)槠涮攸c(diǎn)之一就是會(huì)存在數(shù)據(jù)冗余,但是數(shù)據(jù)冗余對(duì)于MaxCompute這種離線數(shù)據(jù)倉庫來說,存儲(chǔ)成本并不是很高,因?yàn)槠涠紝儆赟ATA盤的存儲(chǔ),這樣的存儲(chǔ)成本是很低的,而傳統(tǒng)的數(shù)據(jù)倉庫比如使用Oracle等其他的關(guān)系型數(shù)據(jù)庫構(gòu)建的數(shù)據(jù)倉庫,大家往往會(huì)選擇3NF的建模方式,這是因?yàn)槠鋽?shù)據(jù)冗余存儲(chǔ)成本會(huì)很高,磁盤很貴。
總之,在MaxCompute上推薦大家使用維度建模,使用星型建?;蛘哐┗ㄐ徒5姆绞?,這無論對(duì)于后續(xù)的運(yùn)維還是后續(xù)對(duì)于數(shù)據(jù)的使用而言,都是比較便利的,并且性能也會(huì)好一些。星型模型其實(shí)就是中間一個(gè)事實(shí)表,周邊圍繞著一堆維度表,其結(jié)構(gòu)會(huì)簡(jiǎn)單一些,使用比較方便,性能也比較好;對(duì)于雪花模型而言,維度表可能還會(huì)繼續(xù)關(guān)聯(lián)其他的維度表,這種方式就是雪花模型,它會(huì)略微比星型模型復(fù)雜一些。其實(shí)星型模型也可以理解為較為簡(jiǎn)單的雪花模型。這里推薦大家使用星型模型,當(dāng)然如果業(yè)務(wù)非常復(fù)雜,必須要使用雪花型也可以使用。這是因?yàn)樾切湍P碗m然有數(shù)據(jù)冗余,但是其結(jié)構(gòu)比較簡(jiǎn)單,容易理解,而且使用起來只需要A傳給B就可以了,不需要再關(guān)聯(lián)一個(gè)C。
除了上述兩個(gè)較大的關(guān)鍵點(diǎn)之外,還有一些值得注意的小點(diǎn),比如中間表的利用,在這部分主要是將數(shù)倉分為三層,第一層做緩沖,第二層做整合,第三層做應(yīng)用。但是并不是嚴(yán)格地只能分為三層,中間還是會(huì)有一些中間表的,如果能夠利用好中間表則會(huì)增強(qiáng)數(shù)倉的易用性以及整體的性能。其主要是在數(shù)倉的第二層里面,因?yàn)樾枰弦恍?shù)據(jù),但是整合之后的數(shù)據(jù)依舊是明細(xì)的,可能有幾百億甚至幾千億的量級(jí),對(duì)于這些表而言,數(shù)據(jù)量往往很大,而且下游任務(wù)以及依賴于這個(gè)表的報(bào)表任務(wù)有很多,因此可以做一些輕度的匯總,也就是做一些公共的匯總的中間表,這樣應(yīng)用好了可以節(jié)省很多的計(jì)算量和成本的。雖然建議大家利用中間表,但是也不建議使用太多的中間表,這還是因?yàn)橹虚g表越多,依賴的層級(jí)也會(huì)越多。
在某些情況下還需要進(jìn)行拆表,比如某一個(gè)大表字段比較多,但是可能其中某兩三個(gè)字段的產(chǎn)出比較慢,產(chǎn)出很慢可能是因?yàn)槠浼庸み壿嫼軓?fù)雜或者數(shù)據(jù)量比較大導(dǎo)致的,而其他字段產(chǎn)出卻是很快的,此時(shí)就可以將數(shù)據(jù)表拆開,將過慢的字段拆出來,并將原來正常的字段留在原來的表,這樣就可以避免因?yàn)閮蓚€(gè)過慢的字段影響其他業(yè)務(wù),拆表的場(chǎng)景雖然比較常見,但是可能不會(huì)在數(shù)倉建設(shè)初期就出現(xiàn)。
還有一種場(chǎng)景及就是合表,這與拆表是相對(duì)的,當(dāng)大家使用數(shù)倉一段時(shí)間之后會(huì)發(fā)現(xiàn)A業(yè)務(wù)部門出了一些表,B業(yè)務(wù)部門也出了一些表,而這些表或者數(shù)據(jù)可能是重疊的,也可能業(yè)務(wù)含義是一樣的,只不過字段不一樣。對(duì)于這些表而言是可以進(jìn)行合并的,因?yàn)樵诤喜⒅罂梢宰稣w批量加工的SQL,這樣要比多個(gè)表批量加工的SQL復(fù)雜度要低很多,而且性能要好很多。對(duì)于分區(qū)的場(chǎng)景而言,也要合理地設(shè)置MaxCompute的分區(qū)。
此外還有拉鏈算法,這在傳統(tǒng)數(shù)倉里面也會(huì)用到,大家往往會(huì)需要使用拉鏈算法來記錄歷史變化情況。而拉鏈算法會(huì)使得計(jì)算成本變得比較高,尤其在MaxCompute里面或者離線數(shù)倉Hive里面,這是因?yàn)槠錄]有Update的操作,因此需要遍歷全表,需要對(duì)比昨天的全量和今天的增量,甚至是比較昨天的全量和今天的全量,才能得到所想要的拉鏈算法的結(jié)果,這樣的計(jì)算成本對(duì)于MaxCompute而言要高很多。如果數(shù)據(jù)量不大,每天做全量的拉鏈算法也是沒有問題的,只需要考慮保留多久歷史數(shù)據(jù)的問題。而實(shí)際上,有些業(yè)務(wù)不會(huì)關(guān)心這些歷史數(shù)據(jù)的變化問題,對(duì)于這樣的業(yè)務(wù)其實(shí)可以只保留最近多少天的歷史數(shù)據(jù)就可以了。其實(shí)是因?yàn)镸axCompute這邊的數(shù)據(jù)存儲(chǔ)成本很低,如果不使用拉鏈算法,那么就意味著數(shù)據(jù)冗余會(huì)高很多,所以其實(shí)大家可以計(jì)算一下每天增量數(shù)據(jù)的存儲(chǔ)成本有多少,再對(duì)比一下數(shù)據(jù)的計(jì)算成本,根據(jù)自己的業(yè)務(wù)進(jìn)行均衡。但是如果每天增量數(shù)據(jù)達(dá)到百億這種級(jí)別,保留全量數(shù)據(jù)肯定是不現(xiàn)實(shí)的,那么就還是去做拉鏈算法。
模型優(yōu)化-合理設(shè)計(jì)分區(qū)
MaxCompute分區(qū)的功能一定要合理利用,這對(duì)于性能會(huì)產(chǎn)生很大的影響,一級(jí)分區(qū)一般都是按照天劃分的,建議大家一天一個(gè)增量或者一天一個(gè)全量來做。二級(jí)分區(qū)的選擇反而會(huì)多一些,首先大家可以選擇是否建立二級(jí)分區(qū),其次大家可以選擇二級(jí)分區(qū)的建立方式。二級(jí)分區(qū)比較適合于在where語句中經(jīng)常使用到的字段,而且這個(gè)字段應(yīng)該是可枚舉的,比如“男”和“女”這樣的。這里還有一個(gè)前提,就是如果這個(gè)字段的值的分布是非常不均勻的,那么就不太建議做二級(jí)分區(qū)。
如下圖中的例子所示,登錄表每天會(huì)有9個(gè)億的數(shù)據(jù),而其中的一個(gè)字段是“是否登錄成功”,成功可能有4億,失敗可能有5億,這就比較適合做二級(jí)分區(qū),因?yàn)楸容^均衡。第二個(gè)例子是用戶訪問表,每天新增20億數(shù)據(jù),其中一個(gè)字段是“頁面訪問狀態(tài)”,成功訪問“202”是18億,而失敗“203”只有0.5億,其他就更少了,這樣的字段就不適合做二級(jí)分區(qū)。在數(shù)量級(jí)不大的情況下,不建議做二級(jí)分區(qū),因?yàn)閹装偃f的數(shù)據(jù)在MaxCompute里面掃描起來也會(huì)很快,在數(shù)據(jù)量大了之后可以再考慮二級(jí)分區(qū),因?yàn)镸axCompute本身對(duì)于分區(qū)有一個(gè)上限就是6萬,也就是一級(jí)分區(qū)乘以二級(jí)分區(qū)的個(gè)數(shù)不能超過6萬個(gè)。
三、同步任務(wù)優(yōu)化
同步任務(wù)優(yōu)化可以從下圖所示的這樣幾個(gè)點(diǎn)進(jìn)行考慮。正如下面的這張PPT中圖所示。數(shù)據(jù)同步其實(shí)就是源庫通過網(wǎng)絡(luò)進(jìn)入到DataWorks或者自定義的調(diào)度資源里,再從DataWorks里面同步到MaxCompute里面,或者反過來從MaxCompute同步到源庫,但是無論怎么說同步就是分為這樣的幾個(gè)點(diǎn):源庫、網(wǎng)絡(luò)1、DataWorks調(diào)度資源、網(wǎng)絡(luò)2以及MaxCompute,出現(xiàn)瓶頸的地方也就在這幾部分中,如果同步任務(wù)運(yùn)行緩慢,那么瓶頸點(diǎn)就只能出現(xiàn)在這幾個(gè)點(diǎn)中。最常見的情況就是從其他數(shù)據(jù)庫向MaxCompute抽取數(shù)據(jù),一般情況下的瓶頸點(diǎn)就在源庫這部分,出現(xiàn)問題大家可以優(yōu)先在源庫處尋找。在網(wǎng)絡(luò)層面,從DataWorks到MaxCompute之間的網(wǎng)絡(luò)2大家一般不用關(guān)心,因?yàn)檫@部分是由阿里云負(fù)責(zé)的,但是從源庫到DataWorks調(diào)度的網(wǎng)絡(luò)1這一段需要由用戶自己保證,公網(wǎng)、內(nèi)網(wǎng)和專線,不同的網(wǎng)絡(luò)環(huán)境中同步的速度也是不一樣的。
再回到同步優(yōu)化的幾個(gè)關(guān)鍵點(diǎn),首先核心同步任務(wù)需要定時(shí)優(yōu)先考慮,如果表的數(shù)據(jù)量比較大或者業(yè)務(wù)的優(yōu)先級(jí)比較高,那么這些絕對(duì)需要提前考慮,因?yàn)槿绻@樣的任務(wù)不提前,那么排在其后面的任務(wù)就會(huì)受到影響。第二點(diǎn)就是網(wǎng)路對(duì)于同步性能的影響,公網(wǎng)、內(nèi)網(wǎng)或者專線對(duì)于性能也會(huì)有一定的影響。第三點(diǎn)就是DataWorks調(diào)度資源對(duì)于同步任務(wù)的影響,大家在DataWorks里面進(jìn)行同步都是使用默認(rèn)的調(diào)度資源,如果同步任務(wù)設(shè)置的并發(fā)過高,就會(huì)導(dǎo)致某一個(gè)任務(wù)會(huì)影響其他任務(wù),比如處理一百萬數(shù)據(jù)啟動(dòng)了20個(gè)并發(fā),顯然這是沒有必要的,但是這樣就占掉了全部的同步任務(wù),導(dǎo)致后續(xù)運(yùn)行SQL以及其他的同步任務(wù)都跑不起來了,這是因?yàn)镈ataWorks的調(diào)度資源不夠了。所以數(shù)據(jù)同步的并發(fā)絕對(duì)不是越多越好的,當(dāng)處理一兩百萬數(shù)據(jù)的時(shí)候,僅需要2到3個(gè)并發(fā)就足夠了。此外,還有就是如何判斷源庫和目標(biāo)庫哪個(gè)是瓶頸點(diǎn)。數(shù)據(jù)同步主要使用的是數(shù)據(jù)集成,當(dāng)離線任務(wù)運(yùn)行完成之后都會(huì)產(chǎn)生這樣的一個(gè)日志,在日志的最后會(huì)顯示開始時(shí)間、結(jié)束時(shí)間以及寫入速度等。在圖中有標(biāo)紅的兩個(gè)點(diǎn),分別是Task WaitWriterTime和Task WaitReaderTime。如果是從RDS往MaxCompute同步,那么Reader指的就是讀取RDS等待的時(shí)間,那Writer指的就是寫入MaxCompute的等待的時(shí)間,哪一邊的時(shí)間更長(zhǎng)就意味著哪一邊存在瓶頸點(diǎn),如果讀的方面時(shí)間更長(zhǎng),那么就需要從RDS或者網(wǎng)絡(luò)1入手,也就是通過兩方面的時(shí)間來判斷瓶頸點(diǎn)究竟在哪一部分。
計(jì)算任務(wù)優(yōu)化
在計(jì)算任務(wù)優(yōu)化部分部分,也只與大家分享在SQL部分開發(fā)者應(yīng)該如何進(jìn)行優(yōu)化。大家平時(shí)在進(jìn)行數(shù)據(jù)處理、數(shù)據(jù)清洗、數(shù)據(jù)轉(zhuǎn)換、數(shù)據(jù)加工等過程中都會(huì)使用到SQL。對(duì)于SQL的優(yōu)化而言,主要集中在這樣的兩個(gè)大方面進(jìn)行:減少數(shù)據(jù)輸入和避免數(shù)據(jù)傾斜。減少數(shù)據(jù)輸入是最核心的一點(diǎn),如果數(shù)據(jù)輸入量太大,包括很多無效的數(shù)據(jù),那么就會(huì)占用很多的計(jì)算資源。而數(shù)據(jù)傾斜是在離線的數(shù)倉里面經(jīng)常會(huì)遇到的,幾乎每個(gè)人都會(huì)遇到,數(shù)據(jù)傾斜也分為好幾種,需要對(duì)應(yīng)地進(jìn)行優(yōu)化。接下來就為大家展開進(jìn)行論述。
在正式展開之前還需要講解一下LogView的用法,因?yàn)橄胍袛鄦栴}究竟是因?yàn)槭裁磳?dǎo)致都需要從分析LogView入手。每一個(gè)SQL執(zhí)行的時(shí)候都會(huì)產(chǎn)生一個(gè)LogView,如下圖中的網(wǎng)址所示,大家可以直接在瀏覽器打開,之后就能打開匯總的頁面,再打開Detail就能看到如下圖所示的明細(xì)頁面。對(duì)于明細(xì)頁面而言,首先需要關(guān)注左側(cè)的執(zhí)行計(jì)劃,也就是分為了多少個(gè)Map、Reduce以及Join節(jié)點(diǎn)。其次需要關(guān)注TimeLine可以看到哪一個(gè)Map運(yùn)行的時(shí)間長(zhǎng),這是尋找數(shù)據(jù)傾斜的依據(jù)。當(dāng)點(diǎn)擊每一個(gè)Map就能看到下面的明細(xì),比如某一個(gè)Map有10個(gè)節(jié)點(diǎn)在跑,那么就會(huì)有10個(gè)點(diǎn)。對(duì)于明細(xì)而言,重點(diǎn)需要關(guān)注的也是TimeLine,需要關(guān)注在分成10個(gè)的節(jié)點(diǎn)里面,究竟哪一個(gè)跑得快,哪一個(gè)跑得慢。下圖中就存在明顯的傾斜,也就是0號(hào)節(jié)點(diǎn)跑得很慢,而其他的節(jié)點(diǎn)跑得就比較快,這樣就是一個(gè)非常明顯Map階段的傾斜。而使用Long-Task則可以快速定位到跑得慢的節(jié)點(diǎn),幫助進(jìn)行快速定位。
當(dāng)然目前也有了比較好用的工具——MaxCompute Studio,其對(duì)于LogView的支持更加強(qiáng)大。在這里面可以直接將剛才的網(wǎng)址粘貼過來,也可以直接連接MaxCompute的項(xiàng)目找到Instance,然后直接點(diǎn)擊Instance查看其執(zhí)行日志,甚至可以將LogView保存在本地或者在本地打開,而網(wǎng)頁版本過期之后就無法打開了。MaxCompute Studio最好用的地方在于其時(shí)序圖功能,時(shí)序圖能夠列出某一個(gè)時(shí)間段,哪一個(gè)節(jié)點(diǎn)跑得快,哪一個(gè)節(jié)點(diǎn)跑得慢,做一個(gè)整體地列舉出來,更加方便地定位到Map、Reduce以及里面小的節(jié)點(diǎn)。還有一個(gè)分析功能,能夠直接為用戶提供結(jié)果,提示用戶哪一個(gè)節(jié)點(diǎn)跑得慢,哪里出現(xiàn)長(zhǎng)尾等問題。
分區(qū)的合理使用
前面講述了分區(qū)應(yīng)該如何設(shè)計(jì),這里著重講解分區(qū)應(yīng)該如何使用。如果表存在一級(jí)分區(qū),那么將分區(qū)的篩選放到了條件里面就是一種錯(cuò)誤的寫法,有可能導(dǎo)致全表掃描。最好的寫法就是像下圖右側(cè)所示的一樣,把Table1的PT先進(jìn)行篩選做一個(gè)子查詢,再把Table2的也做一個(gè)分區(qū)先篩選了作為t2,之后將它們兩個(gè)Join在一起再加上一個(gè)where條件,這樣就能避免全表掃描。對(duì)于PT而言,如果使用了系統(tǒng)自帶的函數(shù),應(yīng)該會(huì)做分區(qū)裁剪,而如果使用了自定義的函數(shù)對(duì)于PT進(jìn)行加工,并放到了where條件里就有可能導(dǎo)致全表掃描,而現(xiàn)在DataWorks里面也會(huì)有系統(tǒng)提示,也便于大家進(jìn)行判斷。
多路輸入
在MaxCompute里面支持多路輸入,可以讀取一個(gè)表的數(shù)據(jù)并將其同時(shí)寫入到兩個(gè)地方,這樣就保證了只做了一次查詢,而可以直接生成兩個(gè)結(jié)果表。下圖是一個(gè)電商的例子,大概就是在銷售訂單表里面有賣家和買家,分別統(tǒng)計(jì)了賣家和買家的數(shù)量分別是多少,以前可能需要拆分成兩個(gè)SQL,而現(xiàn)在可以用一個(gè)SQL同時(shí)統(tǒng)計(jì)兩者的數(shù)量,只需要讀取一次原表就可以了,既能夠節(jié)省時(shí)間,也能夠節(jié)省成本。
慎用SELECT*
因?yàn)镸axCompute里面是列式存儲(chǔ),所以同一列的數(shù)據(jù)都是存儲(chǔ)在一起的,甚至于因?yàn)榱袃?nèi)容相似都會(huì)有一些壓縮算法在里面。而SELECT*查詢?nèi)信c直接查詢兩個(gè)字段的性能差距是非常大的,所以作為數(shù)據(jù)開發(fā)的規(guī)范,無論數(shù)據(jù)量大小都一定不要使用SELECT*就好了。
先過濾JOIN,REDUCE,UDF
還有一個(gè)減少數(shù)據(jù)量的辦法就是在使用Join、Reduce或者UDF的時(shí)候,先做過濾在做具體的計(jì)算或者Join。
合表
合表也是減少數(shù)據(jù)輸入的一種方式,它其實(shí)是從業(yè)務(wù)的角度切入考慮的。比如有一個(gè)業(yè)務(wù)分別用到了T1和T2的兩列,另外一個(gè)業(yè)務(wù)分別用到了T1和T3的兩列,而這兩個(gè)業(yè)務(wù)其實(shí)是可以合并到一起的,但是卻放到了兩個(gè)表,而這樣就可以將這兩個(gè)表合并到一起,這樣只做一次計(jì)算就完成了。
Map傾斜
在LogView里面有一個(gè)Map的時(shí)序,可以看到每個(gè)Map里面有多少個(gè)Instance,里面的哪一個(gè)耗時(shí)比較長(zhǎng)就是發(fā)生了數(shù)據(jù)傾斜。同樣的,在LogView里面也能找到Map的平均執(zhí)行時(shí)間以及最大執(zhí)行時(shí)間,如果兩者相差很大,那么必然出現(xiàn)了傾斜。對(duì)于這樣的問題,從業(yè)務(wù)層面進(jìn)行解決一般是修改上游數(shù)據(jù),讓上游按照均衡的KV值進(jìn)行重新分布。如果業(yè)務(wù)層面無法規(guī)避,那么可以調(diào)整Map的個(gè)數(shù),也就是加大Map的計(jì)算節(jié)點(diǎn),在默認(rèn)情況下是每256M數(shù)據(jù)切一個(gè)節(jié)點(diǎn),可以將其調(diào)小,也就加大了Map處理節(jié)點(diǎn)的個(gè)數(shù),使得數(shù)據(jù)分割得更加均勻一些。
Join傾斜
Join階段的傾斜也是比較常見的,這一現(xiàn)象的發(fā)現(xiàn)與Map傾斜基本相同,也是可以通過LogView判斷。但是其解決方案卻需要分為幾種情況進(jìn)行處理:
-情況1:如果為大表與小表(加載到內(nèi)存不超過512M),則對(duì)小表加MAPJOIN HINT
-情況2:兩個(gè)大表Join,KEY值出現(xiàn)數(shù)據(jù)傾斜,傾斜值為NULL,則需對(duì)NULL進(jìn)行隨時(shí)值處理
-情況3:兩個(gè)大表Join,可以盡量先去重后再Join?? ?
-情況4:兩個(gè)大表Join,業(yè)務(wù)層面考慮優(yōu)化,檢查業(yè)務(wù)的必要性
下圖展現(xiàn)的是Join傾斜的幾個(gè)具體例子,可以分析具體造成傾斜的情況做出相應(yīng)的處理。
Reduce傾斜
Reduce傾斜現(xiàn)象的查看方式和前面的Map以及Join查看的方式相同,可以從TimeLine看到??赡艿那闆r主要有以下四種:
-情況1:GROUP BY 某個(gè)KEY傾斜嚴(yán)重(1. 是否可以過濾 2. 寫法改變,見圖)
-情況2:DISTINCT引起的傾斜(打標(biāo)+GROUPBY)?? ?
-情況3:動(dòng)態(tài)分區(qū)引起的傾斜,盡量避免使用動(dòng)態(tài)分區(qū)
-情況4:窗口函數(shù)引起的傾斜,盡量避免使用窗口函數(shù),要視具體情況而定
Reduce傾斜-DISTINCT
如果是因?yàn)镈ISTINCT造成的數(shù)據(jù)傾斜,有一種解決方法就是打標(biāo)+GROUPBY,比如在下圖的例子中就是對(duì)于求IP段,求美國(guó)IP段、中國(guó)IP段以及總的IP段一共有多少個(gè),左邊這種圖簡(jiǎn)單的寫法,當(dāng)出現(xiàn)IP Key的傾斜就會(huì)使得作業(yè)比較慢,那么就可以將其打散,先求解這條ID的記錄是美國(guó)的還是中國(guó)的,在子查詢里先做這一步,在外面再去求解總的Count或者Sum,從原本Map-Reduce兩個(gè)階段的處理改成了Map-Reduce-Reduce三個(gè)階段處理,這種方案也能解決數(shù)據(jù)傾斜問題。
總結(jié)一下,性能調(diào)優(yōu)歸根結(jié)底還是資源不夠了或者資源使用的不合理,或者是因?yàn)槿蝿?wù)分配的不好,使得某些資源分配和利用不合理。大家需要根據(jù)本文的內(nèi)容考慮如何將自己的任務(wù)打散,保證任務(wù)在規(guī)定的時(shí)間內(nèi)能夠執(zhí)行完畢,同時(shí)能夠保證成本的節(jié)約。當(dāng)然了,大家不僅需要考慮MaxCompute的計(jì)算資源,也需要考慮DataWorks的調(diào)度資源,所以性能優(yōu)化最終還是在和資源作斗爭(zhēng),看資源是否足夠,分配是否合理。
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。?
評(píng)論