數據切片問題:
先給不懂得同學解釋一下概念:
數據塊Block:是HDFS物理數據塊,一個大文件丟到HDFS上,會被HDFS切分成指定大小的數據塊,即Block
數據切片:數據切片是邏輯概念,只是程序在輸入數據的時候對數據進行標記,不會實際切分磁盤數據
Mapper的數量是由切片數量,解釋如下
切片1: 假設文件大小為300M,切片大小為100M,BlockSize為128M,則第一個Block會被切成100M + 28M,100M給DataNode1上的MapTask,剩余的28M需要跨網絡傳輸給DataNode2,同理,DataNode2的Block也需要切分,不過切分需要加上DataNode1剩余的28M,也就是DataNode2需要切分72M,加上28M才是DataNode2上MapTask所需的數據,以此類推,也就解釋了下圖的示意,這種情況最根本的問題就是大數據計算場景中,集群節點之間需要占用大量的網絡IO和磁盤IO,計算效率會大大降低。
切片2: 假設文件依舊300M,但切片的大小SplitSize=BlockSize,則每一個Block就正好是一個MapTask所需數據,不需要切分Block,也就沒有節點間的數據傳輸,效率就回很高,示例如下:
所以:
1. 一個Job的Map階段並行度,也就是Mapper的數量是由提交Job時數據的切片數量決定
2. 每一個Split切片都會分配給一個MapTask並行實例處理
3. 默認情況下SplitSize=BlockSize
4. 切片時不考慮整體數據集,而是逐個針對每一個文件單獨切片(比如Job的數據集是一個目錄下的三個文件,這時切片不會把三個文件加在一起然后做切片,而是直接對每一個文件單獨切片。還用300M那個文件舉例,在SplitSize=BlockSize情況下, 如圖所示為三個Mapper,若再加一個30M的文件,這個30M的文件不會在DataNode3的MapTask上運行,而是會在另一個DataNode4上的MapTask上執行)
以上也就是最基本的MapTask並行度的決定因素,這也就是Mapper數量不能手動指定數量,而是需要計算數據集的大小和切片,乃至DataNode的塊大小,綜合這些因素最后確定的,源碼解釋看下一篇