2017-08-05 2 views
1

J'essaie d'exécuter un worker Python (application PySpark) qui utilise trop de mémoire et mon application se fait tuer mon YARN en raison du dépassement des limites de mémoire (j'essaye de réduire la mémoire utilisation afin de pouvoir engendrer plus de travailleurs).Spark + Python set Seuil de mémoire GC

Je viens de Java/Scala, et Python GC fonctionne de la même que machine virtuelle Java dans ma tête ...

est-il un moyen de dire Python quelle est la quantité de « mémoire disponible », il a? Je veux dire, les GCs Java quand votre taille de tas est presque pleine. Je veux effectuer la même opération sur Python, donc le fil ne tue pas mon application à cause d'utiliser trop de mémoire quand cette mémoire est garbage (je suis sur Python3.3 et il y a des références de mémoire @ ma machine).

J'ai vu les limites matérielles et logicielles des ressources, mais aucune documentation ne dit si les GC se déclenchent sur eux ou non. AFAIK rien ne déclenche les GC par l'utilisation de la mémoire, est-ce que any1 sait le faire?

Merci,

Répondre

1

CPython (Je suppose que c'est celui que vous utilisez) est significativement différent par rapport à Java. La principale méthode de collecte des ordures est reference counting. À moins de traiter des références circulaires (à mon humble avis, ce n'est pas courant dans les flux de production PySpark), vous n'aurez pas besoin de balayages GC complets (les objets liés aux données doivent être collectés une fois que les données sont déversées). Spark est également connu pour tuer les travailleurs Python inactifs, même si vous activez l'option de réutilisation, donc il saute assez souvent GC.

Vous pouvez contrôler le comportement de collecte des ordures CPython utilisant set_threshold méthode:

gc.set_threshold(threshold0[, threshold1[, threshold2]] 

ou déclencheur balayage GC manuellement collect:

gc.collect(generation=2) 

mais dans mon expérience la plupart des problèmes de GC en PySpark viennent de Partie JVM, pas Python.

+0

Merci (encore une fois). Oui, j'utilise Cython. J'ai vu ces options de seuil, mais AFAIK ils ne déclenchent pas sur la quantité de mémoire utilisée, j'ai effectué des collectes manuelles après quelques copies (j'ai d'énormes copys de mémoire de pandas, ne faisant pas le workflow normal de PySpark). Je n'ai pas de problèmes JVM car j'ai changé le sérialiseur en CompressedSerializer (PickleSerializer()) par défaut pour tout (celui du constructeur SparkContext). Mes processeurs sont vstrong/running light par rapport à mes autres soucis (mem essentiellement), donc la Compression fonctionne bien ici (je suis encore plus rapide que sans elle). – BiS

+0

* Ajout à mon commentaire précédent, donc je suppose qu'il n'y a pas d'option pour le faire en fonction de la taille de la mémoire. J'ai lu que le GC par défaut déclenche chaque fois X allocations/allocations (je ne veux pas les attendre, comme YARN pour les GCs), donc pour l'instant je vais l'invoquer manuellement comme tu l'as dit. Ce qui m'intrigue, c'est que no1 mentionne CompressedSerializer pour PySpark, ils l'utilisent par défaut pour la diffusion, mais je n'ai rien trouvé à ce sujet dans Google (je l'ai trouvé en tapant dans le code). Au moins pour moi cela fonctionne à merveille. – BiS