web-dev-qa-db-fra.com

Spark perd println () sur stdout

J'ai le code suivant:

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")

Alors le blueCount n'est pas nul, mais je n'ai eu aucune sortie println ()! Suis-je en train de manquer quelque chose ici? Merci!

15
Edamame

J'ai pu le contourner en créant une fonction utilitaire:

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

Ceci est une question conceptuelle ...

Imaginez que vous avez un gros cluster, composé de nombreux travailleurs disons n travailleurs et ces travailleurs stockent une partition d'un RDD ou DataFrame, imaginez que vous démarrez un map tâche à travers ces données, et à l'intérieur de cette map vous avez une instruction print, tout d'abord:

  • Où ces données seront-elles imprimées?
  • Quel nœud a la priorité et quelle partition?
  • Si tous les nœuds fonctionnent en parallèle, qui sera imprimé en premier?
  • Comment sera créée cette file d'attente d'impression?

Ce sont trop de questions, donc les concepteurs/mainteneurs de Apache-spark a décidé logiquement de supprimer toute prise en charge des instructions print dans les map-reduce opération (cela inclut les variables accumulators et même broadcast).

Cela est également logique parce que Spark est un langage conç pour les très grands ensembles de données. Bien que l'impression puisse être utile pour tester et déboguer, vous ne voudriez pas imprimer chaque ligne d'un DataFrame ou RDD parce qu'ils sont construits pour avoir des millions ou des milliards de lignes! Alors, pourquoi traiter ces questions compliquées alors que vous ne voudriez même pas imprimer en premier lieu?

Pour le prouver, vous pouvez exécuter ce code scala par exemple:

// 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
Alberto Bonsanto