前言
隨著大數(shù)據(jù)時(shí)代的快速發(fā)展,企業(yè)每天需要存儲(chǔ)、計(jì)算、分析數(shù)以萬(wàn)億的數(shù)據(jù),同時(shí)還要確保分析的數(shù)據(jù)具備及時(shí)性、準(zhǔn)確性和完整性。面對(duì)如此龐大的數(shù)據(jù)體系,ETL工程師(數(shù)據(jù)分析師)如何能高效、準(zhǔn)確地進(jìn)行計(jì)算并供業(yè)務(wù)方使用,就成了一個(gè)難題。
作為一家數(shù)據(jù)智能公司,個(gè)推在大數(shù)據(jù)計(jì)算領(lǐng)域沉淀了豐富的經(jīng)驗(yàn)。本篇文章將對(duì)大數(shù)據(jù)離線計(jì)算過(guò)程中出現(xiàn)的任務(wù)緩慢和任務(wù)中斷這兩大痛點(diǎn)問題提出解決思路,期望讀者能夠有所收獲。
一、任務(wù)緩慢
“任務(wù)執(zhí)行緩慢”通常是指任務(wù)的執(zhí)行時(shí)間超過(guò)10個(gè)小時(shí),且不能滿足數(shù)據(jù)使用方對(duì)數(shù)據(jù)及時(shí)性的要求。比如業(yè)務(wù)方需早上就能夠查看T-1的數(shù)據(jù),但是因?yàn)槿蝿?wù)延時(shí),業(yè)務(wù)方只能等到下午或者傍晚才能查詢、瀏覽T-1的數(shù)據(jù),從而無(wú)法及時(shí)發(fā)現(xiàn)經(jīng)營(yíng)問題、進(jìn)行高效決策。因此,對(duì)緩慢任務(wù)進(jìn)行優(yōu)化成了ETL工程師必不可少的一項(xiàng)工作。
在長(zhǎng)期的大數(shù)據(jù)實(shí)踐中,我們發(fā)現(xiàn),緩慢任務(wù)往往具有一定的共性。只要我們能找到問題所在,并對(duì)癥下藥,就能將任務(wù)執(zhí)行時(shí)間大大縮短。個(gè)推將任務(wù)執(zhí)行緩慢的常見問題歸納為以下四點(diǎn):邏輯冗余,數(shù)據(jù)傾斜、大表復(fù)用,慢執(zhí)行器。接下來(lái)會(huì)對(duì)每個(gè)痛點(diǎn)進(jìn)行詳細(xì)闡述。
1、邏輯冗余
“邏輯冗余”往往是因?yàn)镋TL工程師進(jìn)行數(shù)據(jù)處理和計(jì)算時(shí)更關(guān)注處理結(jié)果是否滿足預(yù)期,而未深入考慮是否存在更高效的處理方式,導(dǎo)致原本可通過(guò)簡(jiǎn)單邏輯進(jìn)行處理的任務(wù),在實(shí)際中卻使用了復(fù)雜邏輯來(lái)執(zhí)行。
減少“邏輯冗余”更多地依賴開發(fā)者經(jīng)驗(yàn)的積累和邏輯思維以及代碼能力的提升。這里分享一些高級(jí)函數(shù),希望能夠幫助開發(fā)者進(jìn)一步提升數(shù)據(jù)處理效率。
Grouping sets
分組統(tǒng)計(jì)函數(shù)。這個(gè)函數(shù)可以實(shí)現(xiàn)在一段SQL中輸出不同維度的統(tǒng)計(jì)數(shù)據(jù),避免出現(xiàn)執(zhí)行多段SQL的情況,具體寫法如下:
Lateral view explode()
一行轉(zhuǎn)多行函數(shù)。這個(gè)函數(shù)只能處理array格式數(shù)據(jù),需要配合split()函數(shù)使用,具體寫法如下:
還有其他一些函數(shù)、函數(shù)名及功能如下,具體用法需要讀者自行查詢(可登錄hive官網(wǎng)查詢函數(shù)大全):
find_in_set() :查找特定字符串在指定字符串中的位置
get_json_object():從json串中抽取指定數(shù)據(jù)
regexp_extract():抽取符合正則表達(dá)的指定字符
regexp_replace() :替換符合正則替換指定字符
reverse():字符串反轉(zhuǎn)
2、數(shù)據(jù)傾斜
“數(shù)據(jù)傾斜”是指在MR計(jì)算的過(guò)程中某些Map job需要處理的數(shù)據(jù)量太大、耗時(shí)太長(zhǎng),從而導(dǎo)致整個(gè)進(jìn)程長(zhǎng)時(shí)間無(wú)法結(jié)束,任務(wù)處理進(jìn)度長(zhǎng)時(shí)間卡在99%的現(xiàn)象。
針對(duì)數(shù)據(jù)傾斜的情況,開發(fā)者們可通過(guò)代碼層面進(jìn)行修改,具體操作如下:
使用group by方式替換count(distinct id ) 方式進(jìn)行去重統(tǒng)計(jì)
進(jìn)行大小表關(guān)聯(lián)時(shí)使用mapjoin操作或子查詢操作,來(lái)替換 join操作
group by出現(xiàn)傾斜需要將分組字段值隨機(jī)切分成隨機(jī)值+原始值
join操作避免出現(xiàn)笛卡爾積,即關(guān)聯(lián)字段不要出現(xiàn)大量重復(fù)
3、大表復(fù)用
“大表復(fù)用”,是指對(duì)上億甚至幾十億的大表數(shù)據(jù)進(jìn)行重復(fù)遍歷之后得到類似的結(jié)果。避免大表復(fù)用就要求ETL工程師進(jìn)行系統(tǒng)化的思考,能夠通過(guò)低頻的遍歷將幾十億的大表數(shù)據(jù)瘦身到可重復(fù)使用的中間小表,且同時(shí)支持后續(xù)的計(jì)算。
因此,工程師需要在工程開發(fā)之初就將整體的工程結(jié)構(gòu)考慮進(jìn)去,并且堅(jiān)持“大表僅使用一次”的原則,以提升整個(gè)工程的執(zhí)行效率。
這里介紹一個(gè)實(shí)戰(zhàn)中的例子,供讀者參考:
geqi_win_tmp表中數(shù)據(jù):5000萬(wàn)
4、慢執(zhí)行器
“慢執(zhí)行器”是指數(shù)據(jù)體量過(guò)于龐大時(shí),Hive的底層計(jì)算邏輯已經(jīng)無(wú)法快速遍歷單一分區(qū)中的所有數(shù)據(jù)。
由于在同等資源的情況下,Spark進(jìn)行數(shù)據(jù)遍歷的效率遠(yuǎn)高于MapReduce;且Spark任務(wù)對(duì)資源的搶占程度遠(yuǎn)大于MapReduce任務(wù),可在短時(shí)間內(nèi)占用大量資源高效完成任務(wù),之后快速釋放資源,以提高整個(gè)集群任務(wù)的執(zhí)行效率。
因此,針對(duì)該情況,開發(fā)者可考慮使用pyspark等更為高效的計(jì)算引擎進(jìn)行數(shù)據(jù)的快速遍歷。同時(shí),開發(fā)者也需要有意識(shí)地加強(qiáng)思維訓(xùn)練,養(yǎng)成良好的開發(fā)習(xí)慣,在面對(duì)海量數(shù)據(jù)時(shí)探索更快、更準(zhǔn)、更體系化的計(jì)算和處理方式。
二、任務(wù)中斷
因?yàn)楦鞣N各樣的原因,線上任務(wù)經(jīng)常會(huì)出現(xiàn)被kill掉然后重新執(zhí)行的情況。任務(wù)重新執(zhí)行會(huì)嚴(yán)重浪費(fèi)集群資源,同時(shí)使得數(shù)據(jù)計(jì)算結(jié)果延遲從而影響到業(yè)務(wù)方的數(shù)據(jù)應(yīng)用。如何避免這種現(xiàn)象的發(fā)生呢?個(gè)推是這樣解決該問題的。
個(gè)推的定時(shí)任務(wù)是基于Azkaban調(diào)度系統(tǒng)開發(fā)的,個(gè)推的數(shù)據(jù)分析師主要使用shell、HSQL、MySQL、Pypark四種代碼進(jìn)行數(shù)據(jù)處理,將原始日志清洗、計(jì)算,然后生成公共層、報(bào)表層數(shù)據(jù),最終供業(yè)務(wù)方使用。
因此個(gè)推需要設(shè)定四種代碼執(zhí)行器以支持腳本中對(duì)不同類型代碼的處理。這里主要對(duì)其中的三個(gè)核心內(nèi)容進(jìn)行介紹:代碼塊輸入、執(zhí)行函數(shù)以及循環(huán)器。
1、代碼塊輸入
一般情況下,腳本中的shell、HSQL、MySQL、pypark代碼會(huì)按照順序直接執(zhí)行,不能選擇性執(zhí)行。在實(shí)踐中,我們將代碼塊以字符串的方式賦值給shell中的變量,并在字符串的開頭標(biāo)記是何種類型的代碼,代碼執(zhí)行到具體步驟時(shí)只有賦值操作,不會(huì)解析執(zhí)行,具體如下:
? 執(zhí)行HSQL代碼塊
? 執(zhí)行shell代碼塊
? 執(zhí)行mysql代碼塊
? 執(zhí)行pyspark代碼塊
如此,就實(shí)現(xiàn)了將不同的代碼放入對(duì)應(yīng)的step_n中。在后續(xù)的執(zhí)行器中這些代碼能夠直接執(zhí)行,開發(fā)者只需要關(guān)心邏輯處理即可。
2、執(zhí)行函數(shù)
執(zhí)行函數(shù)是對(duì)shell中變量step_n當(dāng)中的字符串進(jìn)行代碼解析并執(zhí)行。不同類型的代碼塊解析方式不同,因此需要定義不同的執(zhí)行函數(shù)。函數(shù)一般單獨(dú)放在整個(gè)工程的配置文件中,通過(guò)source的方式調(diào)用,具體函數(shù)定義如下:
Hive、MySQL以及shell的執(zhí)行函數(shù)比較簡(jiǎn)單,通過(guò)hive-e 或者eval的方式就可以直接執(zhí)行。pyspark需要配置相應(yīng)的隊(duì)列、路徑、參數(shù)等,還需要在工程中增spark.py文件才能執(zhí)行,此處不做贅述。
3、循環(huán)器
循環(huán)器是斷點(diǎn)執(zhí)行功能的核心內(nèi)容,是步驟的控制器。循環(huán)器通過(guò)判斷shell變量名確定需要執(zhí)行哪一步,通過(guò)判斷變量中字符串內(nèi)容確定使用何種函數(shù)解析代碼并執(zhí)行。
下圖是參考案例,代碼如下:
開發(fā)者需要在腳本的開始定義好整個(gè)代碼的結(jié)束步驟,以確保循環(huán)器正常運(yùn)行;同時(shí),可將開始步驟當(dāng)作腳本參數(shù)傳入,這樣就很好地實(shí)現(xiàn)了任務(wù)的斷點(diǎn)執(zhí)行功能。
總結(jié)
ETL工程中的任務(wù)緩慢和任務(wù)中斷問題是每個(gè)大數(shù)據(jù)工程師都需要面對(duì)和解決的。本文基于個(gè)推大數(shù)據(jù)實(shí)踐,針對(duì)任務(wù)緩慢和任務(wù)中斷問題提出了相應(yīng)解決思路和方案,希望能夠幫助讀者在任務(wù)優(yōu)化以及ETL工程開發(fā)方面擴(kuò)寬思路,提高任務(wù)執(zhí)行效率,同時(shí)降低任務(wù)維護(hù)的人力成本和機(jī)器成本。
編輯:jq
-
存儲(chǔ)
+關(guān)注
關(guān)注
13文章
4226瀏覽量
85578 -
SQL
+關(guān)注
關(guān)注
1文章
753瀏覽量
44032 -
ETL
+關(guān)注
關(guān)注
0文章
20瀏覽量
9384 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4284瀏覽量
62325 -
大數(shù)據(jù)
+關(guān)注
關(guān)注
64文章
8854瀏覽量
137212
原文標(biāo)題:ETL工程師必看!超實(shí)用的任務(wù)優(yōu)化與斷點(diǎn)執(zhí)行方案
文章出處:【微信號(hào):AndroidPush,微信公眾號(hào):Android編程精選】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論