web-dev-qa-db-ja.com

Spark stdoutでprintln()を失う

私は次のコードを持っています:

val blueCount = sc.accumulator[Long](0)
val output = input.map { data =>
  for (value <- data.getValues()) {
    if (record.getEnum() == DataEnum.BLUE) {
      blueCount += 1
      println("Enum = BLUE : " + value.toString()
    }
  }
  data
}.persist(StorageLevel.MEMORY_ONLY_SER)

output.saveAsTextFile("myOutput")

その後、blueCountはゼロではありませんが、println()の出力はありません!ここに何か足りませんか?ありがとう!

15
Edamame

ユーティリティ関数を作成することで回避できました:

object PrintUtiltity {
    def print(data:String) = {
      println(data)
    }
}
1
Edamame

これは概念的な質問です...

nワーカーと、それらのワーカーがRDDまたはDataFrameのパーティションを格納しているとしましょう。mapそのデータにまたがるタスク、およびそのmapの中には、まずprintステートメントがあります。

  • そのデータはどこで印刷されますか?
  • どのノードが優先され、どのパーティションがありますか?
  • すべてのノードが並行して実行されている場合、誰が最初に印刷されますか?
  • この印刷キューはどのように作成されますか?

それらはあまりにも多くの質問であるため、Apache-sparkの設計者/保守者は、map-reduce操作内のprintステートメントに対するサポートを削除することを論理的に決定しました(これにはaccumulatorsbroadcast変数)。

これは、Sparkは言語設計済みであるため、意味があります。印刷はテストやデバッグに役立ちますが、すべての行を印刷する必要はありません。数百または数十億の行を持つように構築されているため、DataFrameまたはRDDの場合!では、そもそも印刷したくない場合でも、なぜこれらの複雑な質問に対処するのでしょうか。

これを証明するために、このscalaコードを実行できます:

// Let's create a simple RDD
val rdd = sc.parallelize(1 to 10000)

def printStuff(x:Int):Int = {
  println(x)
  x + 1
}

// It doesn't print anything! because of a logic design limitation!
rdd.map(printStuff)

// But you can print the RDD by doing the following:
rdd.take(10).foreach(println)
17