Hadoop sqlContext.read…load()和sqlContext.write…save()代码在Spark集群上的何处运行?

Hadoop sqlContext.read…load()和sqlContext.write…save()代码在Spark集群上的何处运行?,hadoop,apache-spark,apache-spark-sql,spark-dataframe,hadoop2,Hadoop,Apache Spark,Apache Spark Sql,Spark Dataframe,Hadoop2,我正在使用Spark Dataframe API从NFS共享加载/读取文件,然后将该文件的数据保存/写入HDFS 我有一个三节点的Spark集群,有一个主节点和两个工作节点。我的Spark群集使用Thread作为群集管理器,因此两个工作节点是Thread NodeManager节点,主节点是Thread ResourceManager节点 我有一个远程位置,比如说/data/files,它安装在所有三个纱线/SPARK节点上,因为它是[/data/files],所有csv文件[不止一个]都存在,

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

我有一个三节点的Spark集群,有一个主节点和两个工作节点。我的Spark群集使用Thread作为群集管理器,因此两个工作节点是Thread NodeManager节点,主节点是Thread ResourceManager节点

我有一个远程位置,比如说/data/files,它安装在所有三个纱线/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;
        }
   }
 }
}
导入java.io.File
导入org.apache.spark.SparkConf
导入org.apache.spark.SparkContext
导入org.apache.spark.sql.DataFrame
导入org.apache.spark.sql.SQLContext
对象testmore 1csv2df{
私有值源:字符串=”file:///data/files/"
private val destination=“hdfs://:8020/raw/”
私有val文件格式:String=“com.databricks.spark.csv”
def main(参数:数组[字符串]):单位={
val conf=new SparkConf().setAppName(“TestMoreThan1CSV2DF”).setMaster(“本地”)
val sc=新的SparkContext(配置)
val sqlContext=新的sqlContext(sc)
val fileArray:Array[File]=new java.io.File(source.listFiles.filter(u.getName.endsWith(“.csv”))
为了(档案){
掷骰子;
}
}
}
def writeDF2HDFS(df:DataFrame,fileFormat:String,header:String,destination:String,partitions:Integer=1){
试一试{
重新分区(分区).write.format(文件格式).option(“header”,header).save(目的地)
}
抓住{
案例ez:OnboardingException=>{
投掷ez;
}
}
}
}
此代码读取共享位置上的所有csv文件 /data/files/并将每个文件写入HDFS.Ex: /数据/文件/f1.csv将作为/raw/f1.csv/part-xxxxx加载到HDFS中 文件

运行此代码时,我无法识别:

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

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

3) 现在我是 在“for”循环中按顺序读取每个文件并处理每个文件 按顺序排列,是否可以使其成为多线程 应用程序,其中每个文件分配给一个线程以执行 端到端并行读写。磁盘IO是否有任何限制 这样做的时候

如有任何快速回复/参考/提示,将不胜感激

问候,, 布比什

很好的实验

1) 您的代码始终在worker上运行。驱动程序仅用于管理工人

2) 是加载()和保存()API在工作节点上运行。它们按顺序工作


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

从另一个线程复制了非常好的解释,用于我的查询:

也在此处复制部分内容: 在转换创建的闭包内发生的所有事情都发生在一个工作进程上。这意味着,如果在映射(…)、过滤器(…)、映射分区(…)、groupBy*(…)、aggregateBy*(…)中传递了某些内容,则会在工作线程上执行。它包括从持久存储器或远程源读取数据

像count、reduce(…)、fold(…)这样的操作通常在驱动程序和工作程序上执行。重型起重作业由工人并行执行,最后的一些步骤,如减少工人的输出,在驾驶员上按顺序执行

其他一切,比如触发动作或转换,都发生在驱动程序上。特别是指需要访问SparkContext的每个操作

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

2) load()和save()在worker上运行,因为我们可以看到加载会创建数据帧[存储在分区内存中],save会在hdfs中创建部分xxxx文件,这表明worker正在这样做

3) 仍在努力做到这一点,一旦做到了,就会回答这个问题


谢谢

Hi@Achyuta nanda sahoo,感谢您的回复。我的假设是所有的转换代码都在worker上运行,而其余的代码都在驱动程序上运行。最后,操作在辅助程序或驱动程序上运行。我仍然不清楚我的理解是否正确。如果load()和save()在工作节点上工作,那么它如何跟踪文件的哪个部分由哪个工作节点读/写???如果你喜欢这个问题,那么请给它一个上升点,这样大多数人都可以达到它,并像你一样提供他们有价值的意见。主操作总是发生在驱动程序节点。主操作意味着从所有节点获取聚合数据。主驱动程序的作用类似于根节点。在树结构图中,根节点是驱动节点,其余节点是工作节点。主驱动程序尝试创建分区/索引。分区是指来自一个文件或多个文件的组数据群集。并将每个集群发送到每个节点。就这样。