spark RDD系列------2.HadoopRDD分割槽的建立以及計算
Spark經常需要從hdfs讀取檔案生成RDD,然後進行計算分析。這種從hdfs讀取檔案生成的RDD就是HadoopRDD。那麼HadoopRDD的分割槽是怎麼計算出來的?如果從hdfs讀取的檔案非常大,如何高效的從hdfs載入檔案生成HadoopRDD呢?本篇文章探討這兩個問題。
SparkContext.objectFile方法經常用於從hdfs載入檔案,從載入hdfs檔案到生成HadoopRDD的函式呼叫過程為:
SparkContext.objectFile->
SparkContext.sequenceFile->
SparkContext.hadoopFile->
new HadoopRDD
SparkContext.objectFile方法定義如下:
def objectFile[T: ClassTag]( path: String, minPartitions: Int = defaultMinPartitions): RDD[T] = withScope { assertNotStopped() sequenceFile(path, classOf[NullWritable], classOf[BytesWritable], minPartitions) .flatMap(x => Utils.deserialize[Array[T]](x._2.getBytes, Utils.getContextOrSparkClassLoader)) }
def defaultMinPartitions: Int = math.min(defaultParallelism, 2)
從以上程式碼可知如果不設定載入的hdfs檔案生成的HadoopRDD的分割槽個數,預設最小分割槽個數是2
SparkContext.objectFile方法的minPartitions引數沒有改變,一直傳遞到HadoopRDD的建構函式
HadoopRDD.getPartitions方法用於建立HadoopRDD的分割槽。
在本篇文章中,以如下語句載入hdfs檔案建立HadoopRDD,建立的HadoopRDD分割槽個數最小是24個
hdfs uri為:hdfs://ddos12/val login1RDD = sc.objectFile[String]("/data/login/1448419800022", 24)
hdfs上/data/login/1448419800022/目錄內的檔案情況,如下圖所示:
目錄下存在12個檔案,12個檔案總共10974245位元組,如果按照24個分割槽計算,平均一個分割槽是457260位元組
分割槽的 建立在HadoopRDD.getPartitions方法:
override def getPartitions: Array[Partition] = {
val jobConf = getJobConf()
// add the credentials here as this can be called before SparkContext initialized
SparkHadoopUtil.get.addCredentials(jobConf)
val inputFormat = getInputFormat(jobConf)
if (inputFormat.isInstanceOf[Configurable]) {
inputFormat.asInstanceOf[Configurable].setConf(jobConf)
}
/*
* 確定當前目錄下有多少個分割槽,分割槽個數最小是minPartitions,以及每個分割槽多大,每個分割槽的資料所在的檔案,分割槽資料在檔案中的起始位置
* */
val inputSplits = inputFormat.getSplits(jobConf, minPartitions)
val array = new Array[Partition](inputSplits.size)
for (i <- 0 until inputSplits.size) {
/*建立分割槽*/
array(i) = new HadoopPartition(id, i, inputSplits(i))
}
array
}
根據上面的檔案,建立的分割槽大概資訊如下:
可見總共建立了25個分割槽,通過上圖可得出結論在切分hdfs目錄中的檔案的時候,對每個檔案按照分割槽平均長度457260進行切分,每個分割槽的長度不能大於457260.比如說part-00009檔案,切分成了3個分割槽,最後一個分割槽的長度只有62107位元組
下圖表示了一個index為1分割槽的詳細資訊:
可見裡面包含了分割槽所在的hdfs的檔案,以及分割槽資料在這個檔案的起始位置,分割槽的大小
但是預設情況下,HadoopRDD一個分割槽最大是128M,假設一個檔案大小是1G+10M,但是我設定4個分割槽,那麼在計算分割槽個數的時候會計算為9個分割槽,最後一個分割槽大小為10M。