2015-12-19 14 views
6

Używam programów Spark na dużym klastrze (dla którego nie mam uprawnień administracyjnych). numpy nie jest zainstalowany na węzłach roboczych. Stąd ja pakiecie numpy z moim programem, ale pojawia się następujący błąd:Numpy i statyczne łączenie

Traceback (most recent call last): 
    File "/home/user/spark-script.py", line 12, in <module> 
    import numpy 
    File "/usr/local/lib/python2.7/dist-packages/numpy/__init__.py", line 170, in <module> 
    File "/usr/local/lib/python2.7/dist-packages/numpy/add_newdocs.py", line 13, in <module> 
    File "/usr/local/lib/python2.7/dist-packages/numpy/lib/__init__.py", line 8, in <module> 
    File "/usr/local/lib/python2.7/dist-packages/numpy/lib/type_check.py", line 11, in <module> 
    File "/usr/local/lib/python2.7/dist-packages/numpy/core/__init__.py", line 6, in <module> 
ImportError: cannot import name multiarray 

Skrypt jest całkiem prosta:

from pyspark import SparkConf, SparkContext 
sc = SparkContext() 

sc.addPyFile('numpy.zip') 

import numpy 

a = sc.parallelize(numpy.array([12, 23, 34, 45, 56, 67, 78, 89, 90])) 
print a.collect() 

Rozumiem, że błąd występuje, ponieważ numpy dynamicznie ładuje multiarray.so zależność i nawet jeśli mój plik numpy.zip zawiera plik multiarray.so, to jednak dynamiczne ładowanie nie działa z Apache Spark. Dlaczego tak? A w jaki sposób tworzysz samodzielny moduł numpy z łączeniem statycznym?

Dzięki.

+0

można pokazać, jak utworzyć plik zip? – zero323

+0

@ zero323: 'zip -r ~/numpy.zip/usr/local/lib/python2.7/dist-packages/numpy' – abhinavkulkarni

+0

Próbujesz skopiować istniejącą instalację? – zero323

Odpowiedz

6

Istnieją co najmniej dwa problemy z twoim podejściem i można je zredukować do prostego faktu, że NumPy jest zależne od wagi ciężkiej.

  • Przede wszystkich pakietach Debiana przyjść z wieloma zależnościami tym libgfortran, libblas, liblapack i libquadmath. Więc nie możesz po prostu skopiować instalacji NumPy i oczekiwać, że wszystko będzie działać (szczerze mówiąc, nie powinieneś robić czegoś takiego, jeśli tak nie było). Teoretycznie możesz spróbować zbudować go za pomocą linku statycznego iw ten sposób wysłać go ze wszystkimi zależnościami, ale trafia on na drugi problem.

  • NumPy jest dość duży sam. O ile 20MB nie wygląda szczególnie imponująco i przy wszystkich zależnościach nie powinno być więcej niż 40MB, to musi być wysyłane do pracowników za każdym razem, gdy rozpoczynasz pracę. Im więcej pracowników masz, tym gorzej. Jeśli zdecydujesz, że potrzebujesz SciPy lub SciKit, może być znacznie gorzej.

Prawdopodobnie to sprawia NumPy naprawdę dobrym kandydatem jest dostarczany z pyFile metody.

Jeśli nie miałeś bezpośredniego dostępu do pracowników, ale wszystkie zależności, w tym pliki nagłówkowe i biblioteka statyczna, były obecne, możesz po prostu spróbować zainstalować NumPy w przestrzeni użytkownika z samego zadania (zakłada się, że pip zainstalowano również) z mniej więcej tak:

try: 
    import numpy as np 

expect ImportError: 
    import pip 
    pip.main(["install", "--user", "numpy"]) 
    import numpy as np 

znajdziesz inne warianty tej metody w How to install and import Python modules at runtime?

Skoro masz dostęp do pracowników o wiele lepszym rozwiązaniem jest utworzenie osobnego środowiska Pythona . Prawdopodobnie najprostszym podejściem jest użycie Anaconda, które może być używane do pakowania zależności innych niż Python i nie zależy od bibliotek systemowych. Możesz łatwo zautomatyzować to zadanie za pomocą narzędzi takich jak Ansible lub Fabric, nie wymaga to uprawnień administracyjnych, a wszystko, czego naprawdę potrzebujesz to bash i jakiś sposób na pobranie podstawowych instalatorów (wget, curl, rsync, scp).

Zobacz także: shipping python modules in pyspark to other nodes?