web-dev-qa-db-fra.com

PySpark sérialisation EOFError

Je lis dans un CSV comme un Spark DataFrame et j'effectue des opérations d'apprentissage automatique dessus. Je reçois toujours une Python sérialisation EOFError - une idée pourquoi? J'ai pensé il peut s'agir d'un problème de mémoire - c'est-à-dire que le fichier dépasse la capacité RAM - mais réduire considérablement la taille du DataFrame n'a pas empêché l'erreur EOF.

Code du jouet et erreur ci-dessous.

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

L'exécution du code ci-dessus avec spark-submit Sur un seul nœud génère à plusieurs reprises l'erreur suivante, même si la taille du DataFrame est réduite avant l'ajustement du modèle (par exemple 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

L'erreur semble se produire dans la fonction pySpark read_int. Code pour lequel est le suivant de spark site :

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

Cela signifie que lors de la lecture de 4 octets dans le flux, si 0 octet est lu, l'erreur EOF est générée. Les documents python sont ici .

1
Abhishek P

Avez-vous vérifié pour voir où dans votre code se produit l'EOError?

Je suppose que cela vient lorsque vous essayez de définir df avec, car c'est le seul endroit dans votre code que le fichier essaie réellement de lire.

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

À chaque point après cette ligne, votre code fonctionne avec la variable df, pas avec le fichier lui-même, il semble donc probable que cette ligne génère l'erreur.

Un moyen simple de tester si c'est le cas serait de commenter le reste de votre code et/ou de placer une ligne comme celle-ci juste après la ligne ci-dessus.

print(len(df))

Une autre façon serait d'utiliser une boucle try, comme:

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

S'il s'avère que cette ligne est celle qui génère l'erreur EOFError, alors vous n'obtiendrez jamais les trames de données en premier lieu, donc essayer de les réduire ne fera aucune différence.

Si c'est la ligne générant l'erreur, deux possibilités viennent à l'esprit:

1) Votre code appelle un ou les deux fichiers .csv plus tôt et ne le ferme pas avant cette ligne. Si c'est le cas, fermez-le simplement au-dessus de votre code ici.

2) Il y a un problème avec les fichiers .csv eux-mêmes. Essayez de les charger en dehors de ce code et voyez si vous pouvez les mettre correctement en mémoire en premier lieu, en utilisant quelque chose comme csv.reader, et manipulez-les de la manière que vous attendez.

1
misterflister