Сериализация PySpark EOFError

Я читаю CSV как Spark DataFrame и выполняю на нем операции машинного обучения. Я продолжаю получать сериализацию Python EOFError - любая идея, почему? Я думал, что это может быть проблема с памятью, то есть файл, превышающий доступную оперативную память, - но значительно уменьшив размер 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 на одном node многократно вызывает следующую ошибку, даже если размер 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

Ответ 1

Вы проверили, где в вашем коде возникает EOError?

Я предполагаю, что это произойдет, когда вы попытаетесь определить df, поскольку это единственное место в вашем коде, которое файл действительно пытается прочитать.

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

В каждой точке после этой строки ваш код работает с переменной df, а не с самим файлом, поэтому кажется, что эта строка генерирует ошибку.

Простой способ проверить, если это так, было бы прокомментировать остальную часть вашего кода и/или разместить такую строку прямо после строки выше.

print(len(df))

Другой способ - использовать цикл 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, тогда вы никогда не будете получать фреймы данных в первую очередь, поэтому попытка их сокращения не изменит ситуацию.

Если это линия, порождающая ошибку, на ум приходят две возможности:

1) Ваш код вызывает один или оба из.csv файлов ранее и не закрывает его до этой строки. Если да, просто закройте его над своим кодом здесь.

2) Что-то не так с самими файлами.csv. Попробуйте загрузить их вне этого кода и посмотрите, можете ли вы правильно их перенести в память, используя что-то вроде csv.reader и манипулируя ими так, как вы ожидали.

Ответ 2

Возможно, проверьте формат вашего файла csv до конца. Есть ли что-то в отношении форматирования файлов csv?

Ответ 3

В функции py_park read_int появляется ошибка. Код, который выглядит следующим образом из искрового сайта:

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

Это означает, что при чтении 4 байта из потока, если считывается 0 байтов, возникает ошибка EOF. Документы python здесь.