web-dev-qa-db-fra.com

Spark utilisant python: comment résoudre l'étape x contient une tâche de très grande taille (xxx Ko). La taille de tâche maximale recommandée est de 100 Ko

Je viens de créer python liste de range(1,100000).

L'utilisation de SparkContext a effectué les étapes suivantes:

a = sc.parallelize([i for i in range(1, 100000)])
b = sc.parallelize([i for i in range(1, 100000)])

c = a.Zip(b)

>>> [(1, 1), (2, 2), -----]

sum  = sc.accumulator(0)

c.foreach(lambda (x, y): life.add((y-x)))

Ce qui donne l'avertissement comme suit:

ARN TaskSetManager: l'étape 3 contient une tâche de très grande taille (4644 Ko). La taille de tâche maximale recommandée est de 100 Ko.

Comment résoudre cet avertissement? Existe-t-il un moyen de gérer la taille? Et cela affectera-t-il également la complexité temporelle des mégadonnées?

29
user2959723

Développer le commentaire @ leo9r: pensez à utiliser non pas un python range, mais sc.rangehttps://spark.Apache.org/docs/1.6.0/api/python/pyspark.html#pyspark.SparkContext.range .

Ainsi, vous évitez de transférer une énorme liste de votre pilote aux exécuteurs.

Bien sûr, ces RDD sont généralement utilisés à des fins de test uniquement, vous ne voulez donc pas qu'ils soient diffusés.

4
Timofey Chernousov

Spark expédie nativement une copie de chaque variable pendant l'expédition de la tâche. Pour de grandes tailles de telles variables, vous pouvez utiliser Broadcast Variables

Si vous rencontrez toujours des problèmes de taille, alors peut-être que ces données devraient être un RDD en soi

modifier: mise à jour du lien

9
Hitesh Dharamdasani

L'idée générale est que PySpark crée autant de processus Java qu'il y a d'exécuteurs, puis envoie des données à chaque processus. S'il y a trop peu de processus, un goulot d'étranglement de la mémoire se produit sur le Java espace de tas.

Dans votre cas, l'erreur spécifique est que le RDD que vous avez créé avec sc.parallelize([...]) n'a pas spécifié le nombre de partitions (argument numSlices, voir docs ). Et le RDD par défaut à un nombre de partition qui est trop petit (peut-être il est constitué d'une seule partition).

Pour résoudre ce problème, spécifiez simplement le nombre de partitions souhaitées:

a = sc.parallelize([...], numSlices=1000)   # and likewise for b

Lorsque vous spécifiez un nombre de tranches de plus en plus élevé, vous constaterez une diminution de la taille indiquée dans le message d'avertissement. Augmentez le nombre de tranches jusqu'à ce que vous n'ayez plus de message d'avertissement. Par exemple, obtenir

Stage 0 contains a task of very large size (696 KB). The maximum recommended task size is 100 KB

signifie que vous devez spécifier plus de tranches.


Une autre astuce qui peut être utile pour traiter les problèmes de mémoire (mais cela n'est pas lié au message d'avertissement): par défaut, la mémoire disponible pour chaque exécuteur est d'environ 1 Go. Vous pouvez spécifier des quantités plus importantes via la ligne de commande, par exemple avec --executor-memory 64G.

7
Jealie