web-dev-qa-db-fra.com

Comment le sérialiseur Kryo alloue le tampon dans Spark

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?

9
vvladymyrov

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é.

6
vvladymyrov

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

1
dnivog

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.

1
lambzee

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é.

0
Mayukh

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")
0
Ignacio Alorre