摘錄自《Hive 性能調優實戰》
在調優時不希望生成太多的 Map,而把計算任務的等待時間都耗費在 Map 的啓動上;或者不希望生成太多的 Map 對某個文件進行操作,以免引起資源的爭用。這時候就需要對 Map 進行控制。在 Hive 中配置“set mapred.map.tasks=task 數量”無法控制 Map 的任務數,調節 Map 任務數需要一套算法,該算法也和 InputFormat 有密切的關係,具體如下:
- 在默認情況下 Map 的個數 defaultNum = 目標文件或數據的總大小 totalSize/hdfs 集羣文件塊的大小 blocksize;
- 當用戶指定 mapred.map.tasks,即爲用戶期望的 Map 大小,用 expNum 表示,這個期望值計算引擎不會立即採納,它會獲取 mapred.map.tasks 與 defaultNum 的較大值,用 expMaxNum 表示,作爲待定選項;
- 獲取文件分片的大小和分片個數,分片大小爲參數 mapred.min.split.size 和 blockSize 間的較大值,用 splitMaxSize 表示,將目標文件或數據的總大小除以 splitMaxSize 即爲真實的分片個數,用 realSplitNum 表示;
- 獲取 realSplitNum 和 expMaxNum 較小值則爲實際的 Map 個數;
上述算法用代碼表達如下:
defaultNum = totalSize/blockSize;
expNum = mapred.map.tasks;
expMaxNum = max(expNum, defaultNum);
splitMaxSize = max(mapred.min.split.size, blockSize)
realSplitNum = totalSize/splitMaxSize;
實際的 map 個數 = min(expMaxNu, realSplitNum)
通過上面的邏輯知道:
- 減少 Map 個數,需要增大 mapred.min.split.size 的值,減少 mapred.map.tasks 的值;
- 增大 Map 個數,需要減少 mapred.min.split.size 的值,增大 mapred.map.tasks 的值;