Aidez-nous à comprendre comment le sérialiseur Kryo alloue de la mémoire à sa mémoire tampon.
Mon application Spark échoue lors d'une étape de collecte lorsqu'elle tente de collecter environ 122 Mo de données sur un pilote à partir de travailleurs.
com.esotericsoftware.kryo.KryoException: Buffer overflow. Available: 0, required: 57197
at com.esotericsoftware.kryo.io.Output.require(Output.Java:138)
at com.esotericsoftware.kryo.io.Output.writeBytes(Output.Java:220)
at com.esotericsoftware.kryo.io.Output.writeBytes(Output.Java:206)
at com.esotericsoftware.kryo.serializers.DefaultArraySerializers$ByteArraySerializer.write(DefaultArraySerializers.Java:29)
at com.esotericsoftware.kryo.serializers.DefaultArraySerializers$ByteArraySerializer.write(DefaultArraySerializers.Java:18)
at com.esotericsoftware.kryo.Kryo.writeObjectOrNull(Kryo.Java:549)
at com.esotericsoftware.kryo.serializers.DefaultArraySerializers$ObjectArraySerializer.write(DefaultArraySerializers.Java:312)
at com.esotericsoftware.kryo.serializers.DefaultArraySerializers$ObjectArraySerializer.write(DefaultArraySerializers.Java:293)
at com.esotericsoftware.kryo.Kryo.writeClassAndObject(Kryo.Java:568)
at org.Apache.spark.serializer.KryoSerializerInstance.serialize(KryoSerializer.scala:161)
at org.Apache.spark.executor.Executor$TaskRunner.run(Executor.scala:213)
Cette exception est indiquée après avoir augmenté la mémoire du pilote en 3Gb et celle de l'exécuteur en 4 Go et augmenté la taille de la mémoire tampon pour kryoserializer (j'utilise Spark 1.3)
conf.set('spark.kryoserializer.buffer.mb', '256')
conf.set('spark.kryoserializer.buffer.max', '512')
Je pense que j'ai défini le tampon pour être assez grand, mais mon application pour étincelles ne cesse de planter. Comment puis-je vérifier quels objets utilisent le tampon Kryo sur un exécuteur? Y a-t-il un moyen de le nettoyer?
Dans mon cas, le problème consistait à utiliser un nom de propriété incorrect pour la taille maximale de la mémoire tampon.
Jusqu'à la version 1.3 de Spark le nom de la propriété est spark.kryoserializer.buffer.max.mb
- il porte finalement ".mb
". Mais j'ai utilisé le nom de la propriété de Spark 1.4 docs - spark.kryoserializer.buffer.max
.
En conséquence, spark app utilisait la valeur par défaut - 64 Mo. Et ce n’était pas suffisant pour la quantité de données que je traitais.
Après avoir fixé le nom de la propriété à spark.kryoserializer.buffer.max.mb
, mon application a bien fonctionné.
Utilisez conf.set('spark.kryoserializer.buffer.max.mb', 'val')
pour définir le tampon kryoserializer
et gardez à l'esprit que val
devrait être inférieur à 2048, sinon vous obtiendrez encore une erreur indiquant que le tampon devrait être inférieur à 2048 Mo
La solution consiste à installer spark.kryoserializer.buffer.max
à 1g
dans spark-default.conf
et à redémarrer les services d'étincelle
Cela a au moins fonctionné pour moi.
J'utilise spark 1.5.2 et j'ai eu le même problème. Régler spark.kryoserializer.buffer.max.mb
sur 256 l’a corrigé.
Maintenant spark.kryoserializer.buffer.max.mb
est obsolète
WARN spark.SparkConf: La clé de configuration 'spark.kryoserializer.buffer.max.mb' est obsolète à partir de Spark 1.4 et et peuvent être supprimés à l'avenir. Veuillez utiliser la nouvelle clé "spark.kryoserializer.buffer.max" à la place.
Vous devriez plutôt utiliser:
import org.Apache.spark.SparkConf
val conf = new SparkConf()
conf.set("spark.kryoserializer.buffer.max", "val")