如何格式化spark中的打印输出

时间:2015-04-25 04:06:03

标签: scala apache-spark

我得到一个RDD[(String, Array[String])]和两个函数,用于查找给出电影ID的电影名称。

 def find_name1( n : String, m: Map[String,String]) = {
    print(n+":")
    println(m.get(n).mkString)
  }
  def find_name2(n:Array[String], m: Map[String,String]) = {
    print("here is what we recommend:")
    for(i<-0 until n.length)
    {
      print(n(i)+":"+m.get(n(i)).mkString+",")
    }
    println()
  }  

然后我以这种方式打印工作

data.foreach{x=>find_name1(x._1,m.toMap)
      find_name2(x._2,m.toMap)} 

结果应该是四公园,但首先看起来有线。它是:

1375:1694:Apostle, The (1997)
Star Trek III: The Search for Spock (1984)
here is what we recommend:here is what we recommend:1373:Star Trek V: The Final Frontier (1989),1372:Star Trek VI: The Undiscovered Country (1991),994:Big Night (1996),329:Star Trek: Generations (1994),1810:Primary Colors (1998),2641:Superman II (1980),1120:People vs. Larry Flynt, The (1996),1371:Star Trek: The Motion Picture (1979),281:Nobody's Fool (1994),1635:Ice Storm, The (1997),

为什么前两个id不打印为格式:ID:Name。看起来在RDD:data中没有逐行完成打印工作。有没有人能告诉我为什么会这样?我如何根据需要格式化输出。

2 个答案:

答案 0 :(得分:2)

从RDD获取此类报告的一种方法是转换数据,直到您需要所有项目,然后在最终转换中生成实际报告。

此外,不鼓励副作用功能,因为它们会在分布式环境中产生非确定性结果(在println的情况下,如果你使用的是群集,你甚至不会看到它们。这只能起作用在本地模式下,因此它不可扩展)

我建议进行以下更改(*):

def findMovieTitle(id: String) : String = ???

val recommendationReportRDD = movieDataRDD.map{case (id, recommendations) =>    
    val formatId: String => String = id => s"$id: ${findMovieTitle(id)}"    
    val recomStr = recommendations.map(id => formatId(id)).mkString(","))

    s"${formatId(id)}. We recommend: $recomStr"
}

现在,您可以灵活地决定如何处理报告。

你可以打印出来:

recommendationReportRDD.collect.foreach(println _)

但是,您也可以将其保存到文件中:

recommendationReportRDD.saveAstTextFile("path/to/report.txt")

(*)代码用于说明目的。未编译或测试。

答案 1 :(得分:0)

几乎RDD所发生的一切都是并行完成的,所以如果你想让它以线性顺序做某事,你应该在这样的操作之前调用collect()