NullPointerException en Scala Étincelle, semble être causé type de collection?
sessionIdList est de type :
scala> sessionIdList
res19: org.apache.spark.rdd.RDD[String] = MappedRDD[17] au distinctes à :30
Lorsque j'essaie d'exécuter le code ci-dessous :
val x = sc.parallelize(List(1,2,3))
val cartesianComp = x.cartesian(x).map(x => (x))
val kDistanceNeighbourhood = sessionIdList.map(s => {
cartesianComp.filter(v => v != null)
})
kDistanceNeighbourhood.take(1)
- Je recevoir exception :
14/05/21 16:20:46 ERROR Executor: Exception in task ID 80
java.lang.NullPointerException
at org.apache.spark.rdd.RDD.filter(RDD.scala:261)
at $line94.$read$$iwC$$iwC$$iwC$$iwC$$anonfun$1.apply(<console>:38)
at $line94.$read$$iwC$$iwC$$iwC$$iwC$$anonfun$1.apply(<console>:36)
at scala.collection.Iterator$$anon$11.next(Iterator.scala:328)
at scala.collection.Iterator$$anon$10.next(Iterator.scala:312)
at scala.collection.Iterator$class.foreach(Iterator.scala:727)
Cependant, si j'utilise :
val l = sc.parallelize(List("1","2"))
val kDistanceNeighbourhood = l.map(s => {
cartesianComp.filter(v => v != null)
})
kDistanceNeighbourhood.take(1)
Alors aucune exception n'est affiché
La différence entre les deux fragments de code, c'est que dans le premier extrait sessionIdList est de type :
res19: org.apache.spark.rdd.RDD[String] = MappedRDD[17] at distinct at <console>:30
et dans le deuxième extrait de "l" est de type
scala> l
res13: org.apache.spark.rdd.RDD[String] = ParallelCollectionRDD[32] at parallelize at <console>:12
Pourquoi est-ce une erreur survenant ?
Dois-je convertir sessionIdList à ParallelCollectionRDD afin de résoudre ce problème ?
- Pouvez-vous faire de votre code autonome?
- tout le code, à l'exception d'un peuplées ParallelCollectionRDD est inclus afin de recréer l'exception. Je ne sais pas comment créer un peuplées ParallelCollectionRDD
Vous devez vous connecter pour publier un commentaire.
Étincelle ne prend pas en charge l'imbrication des Rdd (voir https://stackoverflow.com/a/14130534/590203 pour une autre occurrence du même problème), de sorte que vous ne pouvez pas effectuer des transformations ou des actions sur les Rdd à l'intérieur d'autres RDD opérations.
Dans le premier cas, vous êtes témoins d'un NullPointerException jeté par le travailleur lorsqu'il tente d'accéder à un SparkContext objet qui est présent uniquement sur le conducteur et non pas les travailleurs.
Dans le second cas, mon intuition est que le travail était exécuté localement sur le pilote et travaillé purement par accident.
local
mode, mais ne parviennent pas à un cluster, ou qui réussissent ou qui échouent basée sur les caprices de l'endroit où les tâches sont planifiées.Ses une question raisonnable et j'ai entendu qu'il a demandé à un certain nombre de fois que. Je vais essayer de prendre un coup de couteau à expliquer pourquoi cela est vrai, parce que cela pourrait aider.
Imbriquée RDDs sera toujours lever une exception dans la production. Les appels de fonctions imbriquées, comme je pense que vous décrivez ici, si cela signifie l'appel d'un RDD fonctionnement à l'intérieur d'un RDD opération, entraînera également des défaillances de cause car c'est la même chose. (Rdd sont immuables, de sorte que l'exécution d'une RDD opération comme une "carte" est équivalent à la création d'un nouveau CA.) La possibilité de créer des listes de Rdd est une conséquence nécessaire de la manière dont le CA est défini et la façon dont l'Application Spark est mis en place.
Un RDD est un système distribué collection d'objets (appelés partitions) qui vivent sur la bougie d'Exécuteurs testamentaires. Spark exécuteurs testamentaires ne peut pas communiquer les uns avec les autres, seulement avec l'Étincelle de pilote. Le RDD opérations sont toutes calculées en morceaux sur ces partitions.Parce que le CA de l'exécuteur testamentaire de l'environnement n'est pas récursive (c'est à dire que vous pouvez configurer une Étincelle pilote pour être sur une étincelle exécuteur testamentaire avec des sous exécuteurs) ni un EDR.
Dans votre programme, vous avez créé une distribué collection de partitions d'entiers. Vous êtes alors l'exécution d'une opération de cartographie. Lorsque l'Étincelle pilote voit une opération de cartographie, il envoie les instructions pour effectuer le mappage pour les exécuteurs testamentaires, qui effectuent la transformation sur chaque partition en parallèle. Mais votre cartographie ne peut pas être fait, parce que sur chaque partition que vous essayez d'appeler le "tout CA" pour effectuer un autre travail distribué. Cela ne peut pas être fait, parce que chaque partition n'a pas accès à l'information sur les autres partitions, si elle l'a fait, le calcul ne pouvait pas s'exécuter en parallèle.
Ce que vous pouvez faire à la place, parce que les données dont vous avez besoin dans la carte est probablement de petite taille (puisque vous faites un filtre et le filtre ne nécessite pas de toutes les informations au sujet de sessionIdList) est d'abord de filtrer l'ID de session de la liste. Puis recueillir la liste pour le pilote. Puis de les diffuser aux exécuteurs, où vous pouvez l'utiliser dans la carte. Si la liste de sessionID est trop grande, vous aurez probablement besoin de faire une jointure.