计算outputMetrics的输出行数Apache Spark错误

时间:2017-06-13 17:33:43

标签: scala apache-spark apache-spark-sql

所以我读了这个答案Spark: how to get the number of written rows?How to get the number of records written (using DataFrameWriter's save operation)?,这真的很有帮助,它对我的​​输入有用。

但是对于输出由于某种原因它总是没有,即使我在我的代码中多次写入镶木地板。 (taskEnd.taskMetrics.outputMetrics = None)总是没有。

添加了带累加的示例代码,但输出仍然没有给出输入行的正确结果,它似乎可以正确地用于累积。

我正在使用Scala和Spark 1.6。

我有两个问题。

  1. 如何使用spark 1.6

  2. 解决这个问题
  3. 使用较新版本的spark可以正常工作。

  4. 附件是我登录Spark 1.6

    var sc = new SparkContext(sparkConf)
    sc.addSparkListener(new SparkListener() {
      override def onTaskEnd(taskEnd: SparkListenerTaskEnd) {
        synchronized {
          if (taskEnd.taskInfo.accumulables.nonEmpty) {
    
            for (i <- 0 until 6) {
              println()
              if (taskEnd.taskInfo.accumulables.length > i) {
                println("value of i " + i)
                println("name = " + taskEnd.taskInfo.accumulables(i).name)
                println("value =  " + taskEnd.taskInfo.accumulables(i).value)
              }  
    
          if (taskEnd.taskMetrics.inputMetrics != None) {
            println("input records " + taskEnd.taskMetrics.inputMetrics.get.recordsRead)
            inputRecords += taskEnd.taskMetrics.inputMetrics.get.recordsRead
          }
          else {
            println("task input records are empty")
          }
    
        }
      }
    })
    

    这就是我写给镶木地板的方式。我不使用savesAsTable而不是.parquet我需要使用.savesAsTable来记录输出变化。我正在使用Databricks csv来读取我的数据框

    df_esd.write.mode("append")
      .partitionBy("dt_skey")
      .parquet(esd_hdfs_loc)
    

    非常感谢任何帮助。

    更新了一些图片,以便在运行上述代码时输出。 内部循环的示例输出,通过累积量

    enter image description here

    enter image description here

    从这两张图片中可以看出,所写行的日志信息量不大,但其他累积量的信息量更多。 实际上它只是增加了由一个写的行,这没有任何意义,因为我正在编写数百万条记录并在下一条记录中注意它只是为写入的行打印了8条。

    但是在运行它的代码结束时,我得到了这个。

    enter image description here

    当我在db中验证这是否是写入的行数时。

    enter image description here

    它是相同的对我而言,似乎最后一个数字是写入的行数。即使它没有被称为。只是说行数。 同样在代码的末尾只有一行计数而不是其他5个累加量。 只有那个。 感谢

1 个答案:

答案 0 :(得分:1)

如果你看一下

taskEnd.taskInfo.accumulables

您会看到它与AccumulableInfo中的ListBuffer按顺序捆绑在一起。

AccumulableInfo(1,Some(internal.metrics.executorDeserializeTime),Some(33),Some(33),true,true,None), 
AccumulableInfo(2,Some(internal.metrics.executorDeserializeCpuTime),Some(32067956),Some(32067956),true,true,None), AccumulableInfo(3,Some(internal.metrics.executorRunTime),Some(325),Some(325),true,true,None), 
AccumulableInfo(4,Some(internal.metrics.executorCpuTime),Some(320581946),Some(320581946),true,true,None), 
AccumulableInfo(5,Some(internal.metrics.resultSize),Some(1459),Some(1459),true,true,None), 
AccumulableInfo(7,Some(internal.metrics.resultSerializationTime),Some(1),Some(1),true,true,None), 
AccumulableInfo(0,Some(number of output rows),Some(3),Some(3),true,true,Some(sql)

您可以清楚地看到输出行的数量位于listBuffer的第7个位置,因此获取正在写入的行的正确方法是

taskEnd.taskInfo.accumulables(6).value.get