簡體   English   中英

Spark textFile 與 WholeTextFiles

[英]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

這不准確:

  1. textFile加載一個或多個文件,每一作為結果 RDD 中的一條記錄 如果文件足夠大(取決於請求的分區數、Spark 的默認分區數和底層文件系統),單個文件可能會被拆分為多個分區。 一次加載多個文件時,此操作“丟失”了記錄與包含它的文件之間的關系 - 即無法知道哪個文件包含哪一行。 RDD 中記錄的順序將遵循文件的字母順序,以及文件中記錄的順序(順序不會“丟失”)。

  2. 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 更好

  1. textfile() 讀取文本文件並返回字符串的 RDD。 例如 sc.textFile("/mydata.txt") 將創建 RDD,其中每一行都是一個元素。

  2. 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM