2017-04-08 1 views
1

j'ai une exception « Tâche non sérialisable » quand je lance un programme Scala Spark avecSpark programmation Scala pour ne pas les objets sérialisables et fonctions

  • Spark RDD est de ne pas le type sérialisable (classe java)
  • appelé fonctions sont d'une classe non sérialisable (classe java, encore une fois)

mon code est quelque chose comme ça

object Main{ 
    def main(args : Array(String){ 
     ... 
     var rdd = sc.textFile(filename) 
        .map(line => new NotSerializableJClass(line)).cache() 
     //rdd is RDD[NotSerializableJClass] 
     ... 
     var test = new NotSerializableJPredicate() 
     rdd = rdd.filter(elem => test.test(elem)) 
     //throws TaskNotSerializable on test Predicate class 
    } 
} 

Je remarque que je peux résoudre la deuxième partie avec

rdd = rdd.filter(elem => (new NotSerializableJPredicate()).test(elem)) 

mais je reçois encore cette exception pour la classe des objets RDD. Et je voudrais d'une autre manière aussi la deuxième partie d'une autre manière juste parce que je ne veux pas créer un grand nombre d'objets PredicateClass.

Pouvez-vous m'aider? Comment puis-je aller de l'avant avec une classe non sérialisable?

+0

Est-ce que 'NotSerializableJClass' est une classe tierce ou une classe définie dans votre application? – himanshuIIITian

Répondre

1

RDD doivent être sérialisable de sorte que vous ne pouvez pas créer un RDD d'une classe non sérialisable.

Pour votre prédicat, vous pouvez l'écrire en utilisant mapPartitions.

rdd.mapPartitions{ 
    part => 
    val test = new NotSerializableJPredicate() 
    part.filter{elem => test.test(elem)} 
    } 

mapPartitons se déroulera une fois par partition, il vous permet d'instancier les classes non sérialisables l'exécuteur, mais il n'a besoin que de le faire une fois par partition plutôt que pour chaque enregistrement.

0

Certaines des règles générales qui m'a aidé à éviter la tâche sérialisation Problème:

Si vous appelez une méthode d'une classe à partir de votre code, Spark devra sérialiser toute la classe contenant les method.Ways aller around peut être l'un des éléments suivants: a> Déclarer la méthode en tant que variable de fonction dans NotSerializableClass; donc au lieu d'écrire: def foo (x: Int) = {bla bla} essayez d'utiliser val foo = (x: Int) => {bla bla} Donc; L'étincelle n'a plus besoin de sérialiser toute la classe maintenant. b> Refactoriser le code pour extraire les parties pertinentes dans une classe séparée peut être le chemin à parcourir dans certains cas. c> Mark objets dans la classe qui ne sont pas réellement nécessaires pour le travail comme @Transient et marquer la classe Serializable