當前位置: 首頁>>技術問答>>正文


Spark讀取/保存本地文件

本文介紹兩點:
1. 如何用Spark讀取本文文件內容。
2. 如何用Spark將數據寫到本地,特別是將大文件寫到本地。

Spark讀取本地文件內容

通常情況下,如果用下麵的代碼讀取本地文件:

val data = sc.textFile("somefile.txt")

直接這樣寫,係統有可能會報錯,正確的讀取方式:

var data = sc.textFile("file:///path to the file/")

原因:SparkContext.textFile內部調用了org.apache.hadoop.mapred.FileInputFormat.getSplits函數;當我們不設置textFile的文件模式的時候,getSplits函數又會調用org.apache.hadoop.fs.getDefaultUri;getDefaultUri這個函數從Hadoop配置中讀取”fs.defaultFS”參數,這個參數通常會在HADOOP_CONF_DIR環境變量中設置為”hdfs://”, 而不是”file://”。”hdfs://”或者”file://”就是前麵說的文件模式,如果textFile中不指定,則默認為”hdfs://”。

當然,將文件先拷貝到hdfs,再textFile也是個不錯的選擇,使用hdfs fs -put命令:

${HADOOP_COMMON_HOME}/bin/hadoop fs -put /localpath/to/data.txt  /hdfspath/to/data.txt

或者,使用hdfs fs -copyFromLocal命令:

${HADOOP_COMMON_HOME}/bin/hadoop fs -copyFromLocal /localpath/to/data.txt  /hdfspath/to/data.txt

Spark寫/保存文件到本地

使用spark將hdfs上的文件保存到本地,如果文件較小,直接collect或者println都可以。如果文件較大,比如有好幾個GB,就需要細致處理了,因為直接collect很可能會打爆spark driver內存。
spark寫大文件到本地的正確方式應該是
1. 直接使用SparkAPI toLocalIterator(需要的本地最大內存等於最大分片占用內存):

val it = rdd.toLocalIterator
while(it.hasNext){
    println(it.next)
}

2.或者遍曆每個partitions,分別collect寫到本地,自己寫邏輯(原理同上,可以自己控製做過濾之類的操作)

val parts = rdd.partitions
for (p <- parts) {
    val idx = p.index
    val partRdd = rdd.mapPartitionsWithIndex(a => if (a._1 == idx) a._2 else Iterator(), true)
    //The second argument is true to avoid rdd reshuffling
    val data = partRdd.collect //data contains all values from a single partition 
                               //in the form of array
    //Now you can do with the data whatever you want: iterate, save to a file, etc.
}

跟讀一樣,寫也可以先saveAsTextFile,然後使用hdfs命令存到本地, 使用hdfs fs -get命令:

${HADOOP_COMMON_HOME}/bin/hadoop fs -get /hdfspath/to/data.txt  /localpath/to/data.txt

或者,使用hdfs fs -copyToLocal命令:

${HADOOP_COMMON_HOME}/bin/hadoop fs -copyToLocal /hdfspath/to/data.txt  /localpath/to/data.txt

————————————————————————————————————————————————————————————————————————
延伸閱讀,附圖:spark client模式,讀寫本地文件一般需要client模式。

spark-client

本文由《純淨天空》出品。文章地址: https://vimsky.com/zh-tw/article/2702.html,未經允許,請勿轉載。