web-dev-qa-db-ja.com

PySparkシリアル化EOFError

CSVをSpark DataFrameとして読み取り、それに対して機械学習操作を実行しています。PythonシリアライゼーションEOFErrorが発生し続けます-理由は何ですか?これはメモリの問題である可能性があります-つまり、ファイルが利用可能RAM-を超えていますが、DataFrameのサイズを大幅に縮小しても、EOFエラーは発生しませんでした。

以下のおもちゃのコードとエラー。

_#set spark context
conf = SparkConf().setMaster("local").setAppName("MyApp")
sc = SparkContext(conf = conf)
sqlContext = SQLContext(sc)

#read in 500mb csv as DataFrame
df = sqlContext.read.format('com.databricks.spark.csv').options(header='true',
     inferschema='true').load('myfile.csv')

#get dataframe into machine learning format
r_formula = RFormula(formula = "outcome ~ .")
mldf = r_formula.fit(df).transform(df)

#fit random forest model
rf = RandomForestClassifier(numTrees = 3, maxDepth = 2)
model = rf.fit(mldf)
result = model.transform(mldf).head()
_

単一のノードで_spark-submit_を使用して上記のコードを実行すると、モデルをフィットする前にDataFrameのサイズが縮小された場合でも、次のエラーが繰り返しスローされます(例:tinydf = df.sample(False, 0.00001)

_Traceback (most recent call last):
  File "/home/hduser/spark1.6/python/lib/pyspark.Zip/pyspark/daemon.py", line 157, 
     in manager
  File "/home/hduser/spark1.6/python/lib/pyspark.Zip/pyspark/daemon.py", line 61, 
     in worker
  File "/home/hduser/spark1.6/python/lib/pyspark.Zip/pyspark/worker.py", line 136, 
     in main if read_int(infile) == SpecialLengths.END_OF_STREAM:
  File "/home/hduser/spark1.6/python/lib/pyspark.Zip/pyspark/serializers.py", line 545, 
     in read_int
    raise EOFError
  EOFError
_
27
Tom Wallace

エラーはpySpark read_int関数で発生するようです。 spark site のコードは次のとおりです。

def read_int(stream):
length = stream.read(4)
if not length:
    raise EOFError
return struct.unpack("!i", length)[0]

これは、ストリームから4バイトを読み取るときに、0バイトが読み取られると、EOFエラーが発生することを意味します。python docs is here

1
Abhishek P

コードのどこでEOErrorが発生しているか確認しましたか?

私の推測では、ファイルを実際に読み取ろうとしているのはコード内の唯一の場所なので、dfを定義しようとすると、それが来ると考えられます。

df = sqlContext.read.format('com.databricks.spark.csv').options(header='true',
     inferschema='true').load('myfile.csv')

この行の後のすべての時点で、コードはファイル自体ではなく変数dfを処理しているため、この行がエラーを生成している可能性があります。

これが当てはまるかどうかをテストする簡単な方法は、コードの残りの部分をコメント化するか、上記の行の直後にこのような行を配置することです。

print(len(df))

もう1つの方法は、次のようにtryループを使用することです。

try:
    df = sqlContext.read.format('com.databricks.spark.csv').options(header='true',
     inferschema='true').load('myfile.csv')
except:
    print('Didn't load file into df!')

その行がEOFErrorを生成している行であることが判明した場合、最初にデータフレームを取得することはないため、データフレームを減らしても違いはありません。

それがエラーを生成する行である場合、2つの可能性が思い浮かびます:

1)コードが以前に.csvファイルの一方または両方を呼び出しており、この行の前に閉じていない。その場合は、コードの上で閉じるだけです。

2).csvファイル自体に問題があります。このコードの外でそれらをロードしてみて、csv.readerのようなものを使用して、最初にそれらを適切にメモリに入れ、期待どおりに操作できるかどうかを確認してください。

1
misterflister