您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關如何控制hive中的map數的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
1. 通常情況下,作業會通過input的目錄產生一個或者多個map任務。 主要的決定因素有: input的文件總個數,input的文件大小,集群設置的文件塊大小(目前為128M, 可在hive中通過set dfs.block.size;命令查看到,該參數不能自定義修改); 答案也是不一定。比如有一個127m的文件,正常會用一個map去完成,但這個文件只有一個或者兩個小字段,卻有幾千萬的記錄, 如果map處理的邏輯比較復雜,用一個map任務去做,肯定也比較耗時。 針對上面的問題3和4,我們需要采取兩種方式來解決:即減少map數和增加map數; 如何合并小文件,減少map數? 假設一個SQL任務: Select count(1) from popt_tbaccountcopy_mes where pt = ‘2012-07-04’; 該任務的inputdir/group/p_sdo_data/p_sdo_data_etl/pt/popt_tbaccountcopy_mes/pt=2012-07-04 共有194個文件,其中很多是遠遠小于128m的小文件,總大小9G,正常執行會用194個map任務。 Map總共消耗的計算資源: SLOTS_MILLIS_MAPS= 623,020 我通過以下方法來在map執行前合并小文件,減少map數: set mapred.max.split.size=100000000; set mapred.min.split.size.per.node=100000000; set mapred.min.split.size.per.rack=100000000; set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; 再執行上面的語句,用了74個map任務,map消耗的計算資源:SLOTS_MILLIS_MAPS= 333,500 對于這個簡單SQL任務,執行時間上可能差不多,但節省了一半的計算資源。 大概解釋一下,100000000表示100M, sethive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;這個參數表示執行前進行小文件合并, 前面三個參數確定合并文件塊的大小,大于文件塊大小128m的,按照128m來分隔,小于128m,大于100m的,按照100m來分隔,把那些小于100m的(包括小文件和分隔大文件剩下的), 進行合并,最終生成了74個塊。 如何適當的增加map數? 當input的文件都很大,任務邏輯復雜,map執行非常慢的時候,可以考慮增加Map數,來使得每個map處理的數據量減少,從而提高任務的執行效率。 假設有這樣一個任務: Select data_desc, count(1), count(distinct id), sum(case when …), sum(case when ...), sum(…) from a group by data_desc 如果表a只有一個文件,大小為120M,但包含幾千萬的記錄,如果用1個map去完成這個任務,肯定是比較耗時的,這種情況下,我們要考慮將這一個文件合理的拆分成多個, 這樣就可以用多個map任務去完成。 set mapred.reduce.tasks=10; create table a_1 as select * from a distribute by rand(123); 這樣會將a表的記錄,隨機的分散到包含10個文件的a_1表中,再用a_1代替上面sql中的a表,則會用10個map任務去完成。 每個map任務處理大于12M(幾百萬記錄)的數據,效率肯定會好很多。 看上去,貌似這兩種有些矛盾,一個是要合并小文件,一個是要把大文件拆成小文件,這點正是重點需要關注的地方, 根據實際情況,控制map數量需要遵循兩個原則:使大數據量利用合適的map數;使單個map任務處理合適的數據量; |
感謝各位的閱讀!關于“如何控制hive中的map數”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。