hive如何調整map和reduce的數量

hive的map數量和reduce數量控制

參考文檔:

map數量控制

map數量由以下幾個因素確定

  • 輸入文件的總個數
  • 輸入文件的大小
  • 集群設置的文件塊大?。J128M,可在hive shell中通過set dfs.block.size查看,單位byte)

舉例

文件不足128M則當做一個塊,大于128M則拆分

  1. input目錄下有七個文件,大小均為64M,則共7個map
  2. input目錄下有10M,10M,129M三個文件,則共4個map,其中129M拆分為128M+1M兩個文件
  3. input目錄下有10M,10M,257M三個文件,則共5個map,其中129M拆分為128M+128M+1M三個文件

map數量應該控制在多少

map數量不是越多越好

如果有過多的小文件(大小遠不夠128M),則每個小文件也會當做一個塊,甚至計算時間沒有map任務的啟動和初始化時間,則會造成資源的浪費。

解決方案:合并小文件,減少map數,可通過設置如下參數解決:

  1. map輸入時合并小文件
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;  #執(zhí)行Map前進行小文件合并
set mapred.max.split.size=128000000;  #每個Map最大輸入大小,單位為KB
set mapred.min.split.size.per.node=100000000; #一個節(jié)點上split的至少的大小,單位為KB
set mapred.min.split.size.per.rack=100000000; #一個交換機下split的至少的大小,單位為KB
  1. map輸出時合并小文件
set hive.merge.mapfiles = true #在Map-only的任務結束時合并小文件
set hive.merge.mapredfiles = true #在Map-Reduce的任務結束時合并小文件
set hive.merge.sparkfiles = true #在hive on spark任務后開啟合并小文件
set hive.merge.size.per.task = 256*1000*1000 #合并文件的大小
set hive.merge.smallfiles.avgsize=16000000 #當輸出文件的平均大小小于該值時,啟動一個獨立的map-reduce任務進行文件merge

小文件合并待驗證

保證map處理的所有文件塊都接近128M,效率也不一定高

如果文件中只有一兩個字段,則有過多條數據,此時在一個map中會執(zhí)行的很慢。當任務邏輯復雜,map執(zhí)行非常慢的時候,可以考慮增加Map數,來使得每個map處理的數據量減少,從而提高任務的執(zhí)行效率

解決方案為:計算每個文件塊合適大小maxSize,然后設置以下參數來將文件切分為,文件大小為maxSize的小文件

set mapreduce.input.fileinputformat.split.maxsize=maxSize;

問題:怎樣才算復雜的任務邏輯?map階段可以做哪些復雜的業(yè)務邏輯?進而如何具體操作,確定塊的大?。浚ㄊ峭ㄟ^試驗摸索嗎)

同時存在大文件切分和小文件合并是必要的嗎?

答:在實際處理數據的時候存在多種多樣的情況,根據實際情況控制map數量需要遵從兩個原則:

  1. 大量數據處理需要合適的map數量
  2. 單個map任務處理需要合適的數據量。

只有把握好這兩點才能最大效率的處理數據(類似生活中,一件工作安排給多個人會快一些,但是安排過多的人并不會讓任務更快的完成,相反給這么多人安排工作是一件非常費力的事情)。

reduce數量控制

reduce個數的設定極大影響任務的執(zhí)行效率

reduce數量如何計算

不指定reduce個數的情況下,hive會基于以下兩個參數計算reduce的個數

  1. hive.exec.reducers.bytes.per.reducer,如果要處理的數據大小不大于這個值,則只有1個reduce,否則會有:數據量 / hive.exec.reducers.bytes.per.reducer個reduce。注意這個數據量是map之前的數據文件大小,所以和map輸出的數據量并不一致,只是一種估算。
  2. hive.exec.reducers.max,總的reduce數量不會超過這個值。

具體到reduce數據推算的細節(jié)請閱讀下面文章
《hive中reducetask數量是怎么推算的》。文章里面有代碼講解。以下是節(jié)選的一些內容:

hive.exec.reducers.bytes.per.reducer

此參數從Hive 0.2.0開始引入。在Hive 0.14.0版本之前默認值是1G(1,000,000,000);而從Hive 0.14.0開始,默認值變成了256M(256,000,000),可以參見HIVE-7158和HIVE-7917。這個參數的含義是每個Reduce處理的字節(jié)數。比如輸入文件的大小是1GB,那么會啟動4個Reduce來處理數據。

hive.exec.reducers.max

此參數從Hive 0.2.0開始引入。在Hive 0.14.0版本之前默認值是999;而從Hive 0.14.0開始,默認值變成了1009;可以參見HIVE-7158和HIVE-7917。這個參數的含義是最多啟動的Reduce個數。比如input size/hive.exec.reducers.bytes.per.reducer>hive.exec.reducers.max,那么Hive啟動的Reduce個數為hive.exec.reducers.max;反之為input size/hive.exec.reducers.bytes.per.reducer。這個參數只有在mapred.reduce.tasks/mapreduce.job.reduces設置為負數的時候才有效。

mapred.reduce.tasks/mapreduce.job.reduces

此參數從Hive 0.1.0開始引入。默認值是-1。此參數的含義是Reduce的個數,典型的情況是設置成接近可用節(jié)點的質數。如果mapred.job.tracker的值是local此參數將會被忽略。在Hadoop中此參數的默認值是1;而在Hive中默認值是-1。通過將此參數設置為-1,Hive將自動計算出應該啟動多少個Reduce。

如何調整reduce的數量

  1. 設置hive.exec.reducers.bytes.per.reducer的大小。
  2. 在hadoop的mapred-default.xml中設置reduce的個數或通過hive shell設置set mapreduce.job.reduces=reduceNum;來硬性規(guī)定reduce的個數。一般set mapreduce.job.reduces=-1,這樣生效的是上面1里面的參數hive.exec.reducers.bytes.per.reducer。如果set mapreduce.job.reduces某一個具體值,那就會固定死這個值了。

reduce數量設置多少合適?

reduce個數不是越多越好

  1. 過多的啟動和初始化reduce也會消耗時間和資源
  2. 有多少個reduce就會有多少個輸出文件,如果生成了很多小文件,如果這些小文件作為下一個任務的輸入,則也會出現(xiàn)效率問題

為何有時候設置的reduce數量不起作用?一直是1個reduce?

只有一個reduce的情況,有時候會出現(xiàn)不過多大數據量和怎么硬性規(guī)定都只有一個reduce,共有三種情況會導致這種結果:這三種情況都是全局的,不得不使用一個reduce來完成。

  1. 沒有使用group by這類匯總
  2. 使用了order by
  3. 有笛卡爾積

關于這三種情況下面這篇文章更詳細一點:
https://blog.csdn.net/javastart/article/details/91381168

reduce設置原則

在設置reduce個數的時候也需要考慮這兩個原則:

  1. 使大數據量利用合適的reduce數;
  2. 使單個reduce任務處理合適的數據量。

聽上去好像沒說什么

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容