sqlContext.read ... load()和sqlContext.write ... save()代码在Spark Cluster上运行在哪里?

时间:2017-07-11 06:53:23

标签: hadoop apache-spark apache-spark-sql spark-dataframe hadoop2

我使用Spark Dataframe API从NFS Share加载/读取文件,然后将该文件的数据保存/写入HDFS。

我有一个三节点Spark Cluster,一个主节点和两个Worker节点。我的Spark Cluster使用YARN作为Cluster Manager,因此两个Worker节点是YARN NodeManager节点,主节点是Yarn ResourceManager节点。

我有一个远程位置说/ data / files安装到所有三个YARN / SPARK节点,因为它是[/ data / files]所有csv文件[多个]都存在,我想读从最后写到HDFS。

我在主节点上运行以下代码

import java.io.File
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql.DataFrame
import org.apache.spark.sql.SQLContext

object TestMoreThan1CSV2DF {
  private val source: String = "file:///data/files/"
  private val destination = "hdfs://<myHostIP>:8020/raw/"
  private val fileFormat : String = "com.databricks.spark.csv"

  def main(args:Array[String]):Unit={
    val conf = new SparkConf().setAppName("TestMoreThan1CSV2DF").setMaster("local")
    val sc = new SparkContext(conf)

    val sqlContext = new SQLContext(sc)

    val fileArray: Array[File] = new java.io.File(source).listFiles.filter(_.getName.endsWith(".csv"))

    for(file<-fileArray){
//  reading csv file from shared location and taking whole data in a dataframe
    var df = loadCSV2DF(sqlContext, fileFormat, "true", "true", file.getName)

//      variable for holding destination location : HDFS Location
    var finalDestination: String = destination+file.getName

//  saving data into HDFS
    writeDF2HDFS(df,fileFormat,"true",finalDestination) /// saved using default number of partition = 1
    }
  }

 def loadCSV2DF(sqlContext : SQLContext, fileFormat: String, header : String, inferSchema: String, source: String) : DataFrame = {
   try{
       sqlContext.read.format(fileFormat)
                       .option("header", header) // Use first line of all files as header
                       .option("inferSchema", inferSchema) // Automatically infer data types
                       .load(source)
   }
   catch{
     case ex: OnboardingException => {
            throw ex;
        }
   }
 }

 def writeDF2HDFS(df: DataFrame, fileFormat: String, header: String, destination: String, partitions: Integer = 1){
   try{
       df.repartition(partitions).write.format(fileFormat).option("header",header).save(destination)
   }
   catch{
     Case ez : OnboardingException => {
            throw ez;
        }
   }
 }
}
  

此代码读取共享位置中存在的所有csv文件   / data / files /并将其中的每一个写入HDFS。例如:   /data/files/f1.csv将作为/raw/f1.csv/part-xxxxx加载到HDFS中   文件

在运行此代码时,我无法理解:

  

1)整个代码在哪里运行?它是否在驱动程序上运行?或使用   两个工人?

     

2)load()和save()API是否在工作节点上运行   它并行工作?如果是,那么两名工人如何跟踪   它读过或写过的那段时间?

     

3)截至目前我是   在“for”循环中按顺序读取每个文件并处理每个文件   它们是顺序的,是否可以使它成为多线程   应用程序,其中每个文件分配给一个线程进行执行   端到端读写并行。磁盘IO是否会受到任何约束   这样做的时候?

任何快速回复/参考/指针都将不胜感激。

此致 布佩希

2 个答案:

答案 0 :(得分:1)

从我的查询的另一个线程复制的非常好的解释: differentiate driver code and work code in Apache Spark

在此处复制部分内容: 由转换创建的闭包内发生的一切都发生在一个工人身上。这意味着如果在map(...),filter(...),mapPartitions(...),groupBy *(...),aggregateBy *(...)中传递了某些内容,则会对worker执行。它包括从持久存储或远程源读取数据。

通常在驱动程序和工作程序上执行count,reduce(...),fold(...)等操作。重型工作由工人并行执行,并且一些最后的步骤,例如减少从工人那里收到的输出,依次在驾驶员身上执行。

其他所有内容,例如触发操作或转换都发生在驱动程序上。特别是它意味着每个需要访问SparkContext的动作。

就我的疑问而言: 1)是的main()方法的一部分在驱动程序上运行,但转换发生在

2)load()和save()在worker上运行,因为我们可以看到加载创建数据帧[它存储在分区的内存中]并保存在hdfs中创建part-xxxx文件,这表明工作人员正在这样做

3)仍在努力实现这一目标,一旦完成就会回答这个问题。

谢谢

答案 1 :(得分:0)

好实验!!。

1)您的代码始终在worker上运行。司机程序只是为了管理工人。

2)是load()和save()API在工作节点上运行。他们按顺序工作。

3)使用多线程应用程序:我还没有尝试过。祝你好运“试一试!!”但是你为什么要把自己置于复杂的境地!! SPARK知道如何处理这种情况。