web-dev-qa-db-ja.com

Pyspark --py-filesが機能しません

ドキュメントが示唆するように私はこれを使用します http://spark.Apache.org/docs/1.1.1/submitting-applications.html

spsarkバージョン1.1.0

./spark/bin/spark-submit --py-files /home/hadoop/loganalysis/parser-src.Zip \
/home/hadoop/loganalysis/ship-test.py 

とコードのconf:

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"))

およびスレーブノードは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

parser-src.Zipはローカルでテストされます。

[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>
>>> 

リモートワーカーに関する情報を取得しようとしています。ファイルをコピーしたかどうかを確認します。sys.pathがどのように見えるかを確認します。

更新:これを使用して、Zipファイルが出荷されたことがわかりました。およびsys.pathが設定されました。それでもエラーをインポートします。

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))

クラウドピクルを掘り下げなければならないようです。つまり、クラウドピクルがどのように機能し、最初に失敗するかを理解する必要があります。

: 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',))

更新:

spark 0.8 http://Apache-spark-user-list.1001560.n3.nabble.com/pyspark-Importing-other-py-filesで同じ問題が発生した場合-in-PYTHONPATH-td2301.html

しかし、彼は自分のライブラリをpython dist-packagesとimport works。に入れました。

更新:

OH.gush ..この問題は、Zipファイルとpython importの動作を理解していないことが原因だと思います。私はparser.pyを--py-filesに渡します。 。およびZip .pyファイルのみ(.pycを含まない)も動作するようです。

しかし、その理由はよくわかりませんでした。

17
C19

ドライバースクリプトの上部ではなく、メソッド自体の内部からカスタムモジュールをインポートしてみてください。例:

def parse_record(record):
    import parser
    p = parser.parse(record)
    return p

のではなく

import parser
def parse_record(record):
    p = parser.parse(record)
    return p

Cloud Pickleは、カスタムモジュールがいつインポートされたかを認識しないようです。そのため、メソッドの実行に必要な他のデータと一緒に最上位モジュールをピクルスしようとするようです。私の経験では、これはトップレベルのモジュールが存在するように見えますが、使用可能なメンバーがなく、ネストされたモジュールは期待どおりに使用できないことを意味します。 from A import *を使用してインポートするか、メソッド内(import A.B)からインポートすると、モジュールは期待どおりに機能しました。

8
Gnat

SparkContextのこの関数を試してください

sc.addPyFile(path)

pysparkのドキュメントによると here

今後、このSparkContextで実行されるすべてのタスクの.pyまたは.Zip依存関係を追加します。渡されるパスは、ローカルファイル、HDFS(またはその他のHadoopでサポートされるファイルシステム)のファイル、またはHTTP、HTTPS、FTP URIのいずれかです。

pythonモジュールファイルをパブリッククラウドストレージ(AWS S3など)にアップロードして、URLをそのメソッドに渡します。

より包括的な資料は次のとおりです。 http://www.cloudera.com/documentation/enterprise/5-5-x/topics/spark_python.html

6
Raymond

1つ以上のノードが適切に構成されていないようです。クラスター上のすべてのノードに同じバージョン/構成のPythonがありますか(つまり、すべてにパーサーモジュールがインストールされていますか)?

1つずつ確認する必要がない場合は、スクリプトが作成されているかどうかを確認して、インストールされているかどうかを確認してください。 これ スレッドはそれを行うためのいくつかの方法を示しています。

3
lolcaks

Setuptoolsなどのツールを使用して、Pythonコードをパッケージ化する必要があります。これにより、Java jarファイルに似た.Eggファイルを作成できます。 --py-filesを使用してこのEggファイルのパスを指定します

spark-submit --py-files path_to_Egg_file path_to_spark_driver_file

1
newToJS_HTML

私は同様の問題に直面していました。--py-files_スイッチを使用していても、ワーカーノードはモジュールを検出できませんでした。

私がやったことはいくつかありました-最初に、モジュールがすべてのノードに出荷された後にインポートが行われることを期待して、SparkContext(sc)変数を作成した後にimportステートメントを入れてみましたが、まだ機能しませんでした。その後、_sc.addFile_を試して(コマンドライン引数として送信する代わりに)スクリプト自体にモジュールを追加し、その後モジュールの関数をインポートしました。少なくとも私の場合、これでうまくいきました。

0
apurva.nandan

すべての依存関係を含むZipファイル(example- abc.Zip)を作成します。

sparkコンテキストを作成するときに、Zipファイル名を次のように記述します。

    sc = SparkContext(conf=conf, pyFiles=["abc.Zip"])
0
Prashant Singh

EMRのPySparkはデフォルトでPython 2.6に設定されているため、Python 2.7インタープリター用にインストールされていないことを確認してください

0
noli