使用split_size優化的ODPS SQL的場景
使用split_size優化的ODPS SQL的場景 首先有兩個大背景需要說明如下: 說明1:split_size,設定一個map的最大資料輸入量,單位M,預設256M。使用者可以通過控制這個變數,從而達到對map端輸入的控制。設定語句:set odps.sql.mapper.split.size=256。一般在調整這個設定時,往往是發現一個map instance處理的資料行數太多。 說明2:小檔案越多,需要instance資源也越多,MaxCompute對單個Instance可以處理的小檔案數限制為120個,如此造成浪費資源,影響整體的執行效能(檔案的大小小於塊Block 64M的檔案)。
場景一:單記錄資料儲存太少
原始Logview Detail: 可以發現Job只調起一個Map Instance,供處理了156M的資料,但這些資料共有5千多萬的記錄(單記錄平均3個byte),花費了25分鐘。 此外,從TimeLine看可以發現,整個Job耗費43分鐘,map佔用了超過60%的時間。故可對map進行優化。 優化手段:調小split_size為16M 優化之後的logview: 優化後,可以發現,Job調起了7個Map Instance,耗時4分鐘;某一個Map處理了27M的資料,6百萬記錄。(這裡可以看出set split_size只是向Job提出申請,單不會嚴格生效,Job還是會根據現有的資源情況等來排程Instance)因為Map的變多,Join和Reduce的instance也有增加。整個Job的執行時間也下降到7分鐘。
場景二:用MapJoin實現笛卡爾積
原始logview: 可以發現,Job調起了4個Map,花費了3個小時沒有跑完;檢視詳細Log,某一個Map因為笛卡爾的緣故,生成的資料量暴漲。 綜合考慮,因為該語句使用Mapjoin生成笛卡爾積,再篩選符合條件的記錄,兩件事情都由map一次性完成,故對map進行優化。 策略調低split_size 優化後的logview: ![] 優化後,可以看到,Job排程了38個map,單一map的生成資料量下降了,整體map階段耗時也下降到37分鐘。 回頭追朔這個問題的根源,主要是因為使用mapjoin笛卡爾積的方式來實現udf條件關聯的join,導致資料量暴漲。故使用這種方式來優化,看起來並不能從根本解決問題,故我們需要考慮更好的方式來實現類似邏輯。