J'utilise ce document comme le suggère le document http://spark.Apache.org/docs/1.1.1/submitting-applications.html
spsark version 1.1.0
./spark/bin/spark-submit --py-files /home/hadoop/loganalysis/parser-src.Zip \
/home/hadoop/loganalysis/ship-test.py
et conf dans le code:
conf = (SparkConf()
.setMaster("yarn-client")
.setAppName("LogAnalysis")
.set("spark.executor.memory", "1g")
.set("spark.executor.cores", "4")
.set("spark.executor.num", "2")
.set("spark.driver.memory", "4g")
.set("spark.kryoserializer.buffer.mb", "128"))
et un noeud esclave se plaignent ImportError
14/12/25 05:09:53 WARN scheduler.TaskSetManager: Lost task 0.0 in stage 0.0 (TID 0, ip-172-31-10-8.cn-north-1.compute.internal): org.Apache.spark.api.python.PythonException: Traceback (most recent call last):
File "/home/hadoop/spark/python/pyspark/worker.py", line 75, in main
command = pickleSer._read_with_length(infile)
File "/home/hadoop/spark/python/pyspark/serializers.py", line 150, in _read_with_length
return self.loads(obj)
ImportError: No module named parser
et parser-src.Zip est testé localement.
[hadoop@ip-172-31-10-231 ~]$ python
Python 2.7.8 (default, Nov 3 2014, 10:17:30)
[GCC 4.8.2 20140120 (Red Hat 4.8.2-16)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path.insert(1, '/home/hadoop/loganalysis/parser-src.Zip')
>>> from parser import parser
>>> parser.parse
<function parse at 0x7fa5ef4c9848>
>>>
J'essaie d'obtenir des informations sur le travailleur distant. voyez si elle a copié les fichiers.Quelle est la apparence de sys.path..et c'est délicat.
UPDATE: J'utilise ceci trouvé que le fichier Zip a été expédié. et sys.path était défini. toujours importer obtenir une erreur.
data = list(range(4))
disdata = sc.parallelize(data)
result = disdata.map(lambda x: "sys.path: {0}\nDIR: {1} \n FILES: {2} \n parser: {3}".format(sys.path, os.getcwd(), os.listdir('.'), str(parser)))
result.collect()
print(result.take(4))
il me semble que je dois creuser dans cloudpickle. Ce qui signifie que je dois comprendre comment fonctionne cloudpickle et échoue en premier.
: An error occurred while calling o40.collect.
: org.Apache.spark.SparkException: Job aborted due to stage failure: Task 4 in stage 0.0 failed 4 times, most recent failure: Lost task 4.3 in stage 0.0 (TID 23, ip-172-31-10-8.cn-north-1.compute.internal): org.Apache.spark.api.python.PythonException: Traceback (most recent call last):
File "/home/hadoop/spark/python/pyspark/worker.py", line 75, in main
command = pickleSer._read_with_length(infile)
File "/home/hadoop/spark/python/pyspark/serializers.py", line 150, in _read_with_length
return self.loads(obj)
File "/home/hadoop/spark/python/pyspark/cloudpickle.py", line 811, in subimport
__import__(name)
ImportError: ('No module named parser', <function subimport at 0x7f219ffad7d0>, ('parser.parser',))
METTRE À JOUR:
quelqu'un rencontre le même problème dans l'étincelle 0.8 http://Apache-spark-user-list.1001560.n3.nabble.com/pyspark-Importing-other-py-files-in-PYTHONPATH-td2301.html
mais il a mis sa bibliothèque dans python dist-packages et import. que j'ai essayé et toujours obtenir une erreur d'importation.
METTRE À JOUR:
OH.gush .. Je pense que le problème est causé par le fait que nous ne comprenons pas le comportement du fichier Zip et de l’importation Python..Je passe parser.py à --py-files, cela fonctionne, se plaint d’une autre dépendance . Et ne compresse que le fichier. Les fichiers py [n'incluant pas le .pyc] semblent également fonctionner.
Mais je ne comprenais pas pourquoi.
Essayez d’importer votre module personnalisé depuis la méthode elle-même plutôt que vers le haut du script de pilote, par exemple:
def parse_record(record):
import parser
p = parser.parse(record)
return p
plutôt que
import parser
def parse_record(record):
p = parser.parse(record)
return p
Cloud Pickle ne semble pas reconnaître le moment où un module personnalisé a été importé. Il semble donc essayer de mélanger les modules de niveau supérieur avec les autres données nécessaires à l'exécution de la méthode. D'après mon expérience, cela signifie que les modules de niveau supérieur semblent exister, mais qu'ils ne disposent pas de membres utilisables et que les modules imbriqués ne peuvent pas être utilisés comme prévu. Une fois que vous avez importé avec from A import *
ou depuis l’intérieur de la méthode (import A.B
), les modules ont fonctionné comme prévu.
Essayez cette fonction de SparkContext
sc.addPyFile(path)
Selon la documentation pyspark
ici
Ajoutez une dépendance .py ou .Zip pour toutes les tâches à exécuter ultérieurement sur ce SparkContext. Le chemin d'accès peut être un fichier local, un fichier au format HDFS (ou un autre système de fichiers pris en charge par Hadoop), ou un URI HTTP, HTTPS ou FTP.
Essayez de télécharger votre fichier de module python sur un stockage cloud public (par exemple, AWS S3) et transmettez l’URL à cette méthode.
Voici un matériel de lecture plus complet: http://www.cloudera.com/documentation/enterprise/5-5-x/topics/spark_python.html
Il semble qu'un ou plusieurs nœuds ne soient pas configurés correctement. Tous les nœuds du cluster ont-ils la même version/configuration de Python (c’est-à-dire qu’ils ont tous le module d’analyse syntaxique installé)?
Si vous ne voulez pas vérifier un par un, vous pouvez écrire un script pour vérifier s'il est installé/l'installer pour vous. This thread montre quelques façons de le faire.
Vous devez conditionner votre code Python à l'aide d'outils tels que setuptools. Cela vous permettra de créer un fichier .Egg similaire au fichier jar Java. Vous pouvez ensuite spécifier le chemin de ce fichier Egg en utilisant --py-files
spark-submit --py-files path_to_Egg_file path_to_spark_driver_file
Je rencontrais un problème similaire. Mes nœuds de travail ne pouvaient pas détecter les modules même si j'utilisais le commutateur --py-files
.
Il y a plusieurs choses que j'ai faites - J'ai d'abord essayé de mettre l'instruction import après avoir créé la variable SparkContext (sc) en espérant que l'importation devrait avoir lieu une fois que le module a été livré à tous les nœuds mais que cela ne fonctionnait toujours pas. J'ai ensuite essayé sc.addFile
pour ajouter le module à l'intérieur du script lui-même (au lieu de l'envoyer en tant qu'argument de ligne de commande), puis j'ai importé les fonctions du module. Cela a fait le tour au moins dans mon cas.
Créez des fichiers Zip (exemple- abc.Zip) contenant toutes vos dépendances.
Lors de la création du contexte spark, indiquez le nom du fichier Zip comme suit:
sc = SparkContext(conf=conf, pyFiles=["abc.Zip"])
PySpark sur EMR est configuré pour Python 2.6 par défaut. Assurez-vous donc qu'ils ne sont pas installés pour l'interpréteur Python 2.7.