Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 为什么apache spark中的这两个阶段计算的是同一件事?_Scala_Hadoop_Apache Spark_Apache Spark Sql_Spark Dataframe - Fatal编程技术网

Scala 为什么apache spark中的这两个阶段计算的是同一件事?

Scala 为什么apache spark中的这两个阶段计算的是同一件事?,scala,hadoop,apache-spark,apache-spark-sql,spark-dataframe,Scala,Hadoop,Apache Spark,Apache Spark Sql,Spark Dataframe,我是spark的新手,我有两个长期运行的阶段在做几乎相同的事情。下面是我的伪代码 var metaData = sqlContext.read .format("com.databricks.spark.csv") .option("header", "true") .option("inferSchema", "true") .load(csvFile) val met = broadcast(metaData.dropDuplicates(Seq("col1")))

我是spark的新手,我有两个长期运行的阶段在做几乎相同的事情。下面是我的伪代码

var metaData = sqlContext.read
  .format("com.databricks.spark.csv")
  .option("header", "true") 
  .option("inferSchema", "true") 
  .load(csvFile)

val met = broadcast(metaData.dropDuplicates(Seq("col1")))


val accessLogs = sc.textFile(logFile).filter(line => regex.pattern.matcher(line).matches).map(line => LogParser.parseLogLine(line)).toDF()




val joinOutput = accessLogs.join(met,accessLogs("col1") === met("col1"),"left_outer")

val uniqueDfNames2 = Seq("col0", "col1", "col2", "col3","col4")
val sparseFilter = joinOutput
                    .filter(joinOutput.col("col1").isNotNull)
                    .filter(joinOutput.col("col2").isNotNull)
                    .flatMap(row=>ListParser.parseLogLine(row))
sparseFilter.cache()

val uniqueCount = sparseFilter
                    .filter{r=>r.col0 != null && r.col0 != "" }
                    .map{
                          case(KeyValParse(col0,col1,col2,col3,col4,col5))=>((col0,col1,col2,col3,col4,col5),1)
                        }
                    .distinct().cache()
                    .map {case ((col0,col1,col2,col3,col4),count) => ((col0,col1,col2,col3,col4),1)
                    }
                    .reduceByKey(_+_)
                    .map {case ((col0,col1,col2,col3,col4),count) => (col0,col1,col2,col3,col4,count)
                    }
                    .toDF(uniqueDfNames: _*).cache()

val totalCount = sparseFilter
                  .map{
                        case(Parse(col0,col1,col2,col3,col4,col5))=>((col0,col1,col2,col3,col4),1)
                      }
                  .reduceByKey(_+_)
                  .map{
                        case ((col0,col1,col2,col3,col4),totcount) => (col0,col1,col2,col3,col4,totcount)
                      }
                  .toDF(uniqueDfNames2: _*)
                  .join(uniqueCount,Seq("col0", "col1", "col2", "col3"),"left")
                  .select($"col0",$"col1",$"col2",$"col3",$"unicount",$"totcount")
                  .orderBy($"unicount".desc)
                  .toDF(totalDfNames: _*)

totalCount
  .select("*")
  .write
  .format("com.databricks.spark.csv")
  .option("header", "true")
  .option("delimiter", "|")
  .save(countPath)
我在这里尝试的是根据一些参数从日志中生成unique和totalcount

一切正常,但有两个长期运行的阶段,共享几乎相同的DAG

下面是两个阶段的快照

请看下面给出的两个阶段的屏幕截图。

在完成flatmap任务之前,它们都做相同的事情。 为什么这些不合并为一个阶段? 为什么第11阶段再次读取文件并再次进行所有计算是我猜不到的

对于具有10个执行器(7个内核,15Gb RAM)的20Gb数据来说,几乎需要30分钟才能完成,但我觉得这可以减少到相当低的时间

任何指导都将不胜感激


PS:-对不起,我的图像编辑技能:)

RDD是第一次在操作中计算时缓存的。代码中的第一个操作是“distinct”,即缓存“sparseFilter”RDD时。因此,第一个缓存操作对于后续阶段可能没有用处。第一阶段的输出是一个独特的RDD,但稍后您将提到sparseFilter。因此Spark必须重新计算RDD


我认为这种逻辑可以有一点不同。如果我理解正确,对于totalCount和uniqueCount,代码使用相同的列集(col0、col1、col2、col3、col4)。所以在totalCount计算中,在reduceByKey之后,一个简单的计数应该给出uniqueCount?通过这种方式可以避免额外的distinct、reduceByKey、join等。很抱歉,我在代码中犯了一个错误uniqueCount RDD第一次实际使用col0-col5,并使用distinct,然后使用col0-col4计算计数(将col5视为某种用户ID,我想为唯一用户生成计数)