python - from - ¿Cómo usar clases personalizadas con Apache Spark(pyspark)?
spark map (2)
Probablemente la solución más sencilla es usar el argumento pyFiles
cuando creas SparkContext
from pyspark import SparkContext
sc = SparkContext(master, app_name, pyFiles=[''/path/to/BoTree.py''])
Cada archivo colocado allí se enviará a los trabajadores y se agregará a PYTHONPATH
.
Si está trabajando en un modo interactivo, debe detener un contexto existente utilizando sc.stop()
antes de crear uno nuevo.
También asegúrese de que Spark worker esté usando la distribución de Anaconda y no un intérprete de Python predeterminado. Basado en su descripción es muy probable que el problema. Para configurar PYSPARK_PYTHON
puede usar archivos conf/spark-env.sh
.
En una nota lateral, copiar el archivo a lib
es una solución bastante desordenada. Si desea evitar la pyFiles
archivos con pyFiles
, le recomendaría crear un paquete Python simple o un paquete Conda y una instalación adecuada. De esta manera, puede realizar un seguimiento de lo que está instalado, eliminar paquetes innecesarios y evitar algunos problemas difíciles de depurar.
He escrito una clase implementando un clasificador en python. Me gustaría usar Apache Spark para paralelizar la clasificación de una gran cantidad de puntos de datos usando este clasificador.
- Estoy configurado usando Amazon EC2 en un grupo con 10 esclavos, basado en una ami que viene con la distribución Anaconda de python en él. El ami me permite usar IPython Notebook de forma remota.
- He definido la clase BoTree en un archivo llamado BoTree.py en el maestro en la carpeta /root/anaconda/lib/python2.7/ que es donde están todos mis módulos de python
- He comprobado que puedo importar y usar BoTree.py cuando ejecuto la línea de comandos con chispa desde el maestro (solo tengo que comenzar escribiendo Import BoTree y mi clase BoTree estará disponible
- He utilizado el script /root/spark-ec2/copy-dir.sh de spark para copiar el directorio /python2.7/ en mi clúster.
- Me conecté a uno de los esclavos y traté de ejecutar ipython allí, y pude importar BoTree, así que creo que el módulo se envió a través del clúster con éxito (también puedo ver el archivo BoTree.py en el .. ./python2.7/ carpeta)
- En el maestro que he comprobado, puedo descifrar y desentrañar una instancia de BoTree utilizando cPickle, lo que entiendo es el serializador de pyspark.
Sin embargo , cuando hago lo siguiente:
import BoTree
bo_tree = BoTree.train(data)
rdd = sc.parallelize(keyed_training_points) #create rdd of 10 (integer, (float, float) tuples
rdd = rdd.mapValues(lambda point, bt = bo_tree: bt.classify(point[0], point[1]))
out = rdd.collect()
La chispa falla con el error (solo el bit relevante creo):
File "/root/spark/python/pyspark/worker.py", line 90, in main
command = pickleSer.loads(command.value)
File "/root/spark/python/pyspark/serializers.py", line 405, in loads
return cPickle.loads(obj)
ImportError: No module named BoroughTree
¿Alguien puede ayudarme? Algo desesperado ...
Gracias
Una vez que se adquiere SparkContext, también se puede usar addPyFile
para enviar posteriormente un módulo a cada trabajador.
sc.addPyFile(''/path/to/BoTree.py'')