[英]Spark textFile vs wholeTextFiles
我理解了textFile
為每個文件生成分區的基本原理,而wholeTextFiles
生成了一個pair值的RDD,其中key是每個文件的路徑,value是每個文件的內容。
現在,從技術的角度來看,兩者之間有什么區別:
val textFile = sc.textFile("my/path/*.csv", 8)
textFile.getNumPartitions
和
val textFile = sc.wholeTextFiles("my/path/*.csv",8)
textFile.getNumPartitions
在這兩種方法中,我都生成了 8 個分區。 那么為什么我首先要使用wholeTextFiles
,它比textFile
什么好處呢?
正如您所提到的,主要區別在於textFile
將返回一個 RDD,每行作為一個元素,而wholeTextFiles
返回一個 PairRDD,鍵是文件路徑。 如果不需要根據文件分離數據,只需使用textFile
。
使用textFile
讀取未壓縮文件時,它將數據拆分為 32MB 的塊。 從內存的角度來看,這是有利的。 這也意味着行的順序丟失了,如果應該保留順序,那么應該使用wholeTextFiles
。
wholeTextFiles
將一次讀取文件的完整內容,它不會部分溢出到磁盤或部分垃圾收集。 每個文件將由一個核心處理,每個文件的數據將在一台機器上存儲,這使得負載分配變得更加困難。
textFile
為每個文件生成分區,而wholeTextFiles
生成對值的 RDD
這不准確:
textFile
加載一個或多個文件,每一行作為結果 RDD 中的一條記錄。 如果文件足夠大(取決於請求的分區數、Spark 的默認分區數和底層文件系統),單個文件可能會被拆分為多個分區。 一次加載多個文件時,此操作“丟失”了記錄與包含它的文件之間的關系 - 即無法知道哪個文件包含哪一行。 RDD 中記錄的順序將遵循文件的字母順序,以及文件中記錄的順序(順序不會“丟失”)。
wholeTextFiles
通過將數據加載到PairRDD
,每個輸入文件有一條記錄, wholeTextFiles
保留數據與包含它的文件之間的關系。 該記錄的格式為(fileName, fileContent)
。 這意味着加載大文件是有風險的(可能會導致性能不佳或OutOfMemoryError
因為每個文件都必須存儲在單個節點上)。 分區是根據用戶輸入或 Spark 的配置完成的 - 多個文件可能加載到單個分區中。
一般來說, textFile
服務於僅加載大量數據的常見用例(無論它如何分解為文件)。 僅當您確實需要知道每個記錄的原始文件名,並且您知道所有文件都足夠readWholeFiles
,才應使用readWholeFiles
。
從 Spark2.1.1 開始,以下是 textFile 的代碼。
def textFile(
path: String,
minPartitions: Int = defaultMinPartitions): RDD[String] = withScope {
assertNotStopped()
hadoopFile(path, classOf[TextInputFormat], classOf[LongWritable], classOf[Text],
minPartitions).map(pair => pair._2.toString).setName(path) }
它在內部使用 hadoopFile 讀取本地文件、HDFS 文件和 S3,使用類似file://
、 hdfs://
和s3a://
WholeTextFile 的語法如下
def wholeTextFiles(
path: String,
minPartitions: Int = defaultMinPartitions): RDD[(String, String)] = withScope
如果我們觀察到這兩種方法的語法是相同的,但是textfile用於讀取文件,而WholeTextFiles用於讀取小文件的目錄。 我們也可以使用更大的文件,但性能可能會受到影響。
所以當你想處理大文件時,textFile 是更好的選擇,而如果我們想處理小文件的目錄,wholeTextFile 更好
textfile() 讀取文本文件並返回字符串的 RDD。 例如 sc.textFile("/mydata.txt") 將創建 RDD,其中每一行都是一個元素。
WholeTextFile() 讀取文本文件目錄並返回pairRDD。 例如,如果目錄中的文件很少,則 WholeTextFile() 方法將創建以文件名和路徑為鍵,值是整個文件作為字符串的對 RDD。
為清楚起見,請參見以下示例:-
textFile = sc.textFile("ml-100k/u1.data")
textFile.getNumPartitions()
輸出- 2
即 2 個分區
textFile = sc.wholeTextFiles("ml-100k/u1.data")
textFile.getNumPartitions()
輸出 - 1
即只有一個分區。
簡而言之, wholeTextFiles
從 HDFS、本地文件系統(在所有節點上可用)或任何 Hadoop 支持的文件系統 URI 中讀取文本文件目錄。 每個文件被讀取為一條記錄並以鍵值對的形式返回,其中鍵是每個文件的路徑,值是每個文件的內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.