Dans les systèmes distribués, le transfert de données sur le réseau est la tâche la plus courante. lorsqu’ils ne sont pas gérés efficacement, nous pouvons nous retrouver confrontés à de nombreux problèmes tels qu’une utilisation élevée de la mémoire, des goulots d’étranglement du réseau et des problèmes de performances. La sérialisation joue un rôle important dans les performances de toute application distribuée pour éliminer plusieurs problèmes liés au transfert de données sur le réseau de systèmes distribués.
Sérialisation
Conversion d’objets en un flux d’octets et vice-versa (Désérialisation) de manière optimale pour le transfert sur les nœuds du réseau ou pour le stocker dans un fichier / mémoire tampon. Spark fournit deux bibliothèques de sérialisation avec des modes pris en charge et configurés via spark.serializer
biens:
Sérialisation Java (par défaut)
La sérialisation Java est la sérialisation par défaut utilisée par Spark lorsque nous faisons tourner le pilote. Spark sérialise les objets à l’aide de Java ObjectOutputStream
cadre. La sérialisation d’une classe est activée par la classe implémentant le java.io.Serializable
interface. Les classes qui n’implémentent pas cette interface n’auront aucun de leur état sérialisé ou désérialisé. Tous les sous-types d’une classe sérialisable sont eux-mêmes sérialisables.
Une classe n’est jamais sérialisée, seul l’objet d’une classe est sérialisé. La sérialisation Java est lente et conduit à de grands formats sérialisés pour de nombreuses classes. nous pouvons affiner les performances en étendant java.io.Externalizable
.
Sérialisation Kryo (recommandée par Spark)
public class KryoSerializer extends Serializerimplements Logging, java.io.Serializable
Kryo est un framework de sérialisation Java axé sur la vitesse, l’efficacité et une API conviviale. Il a moins d’empreinte mémoire, ce qui devient très important lorsque vous mélangez et mettez en cache une grande quantité de données. mais n’est pas pris en charge nativement pour sérialiser sur le disque. Les deux méthodes, saveAsObjectFile
sur RDD et objectFile
La méthode sur SparkContext ne prend en charge que la sérialisation Java.
Kryo n’est pas la valeur par défaut en raison de l’enregistrement personnalisé et de l’exigence de configuration manuelle.
Sérialiseur par défaut
Lorsque Kryo sérialise un objet, il crée une instance d’un fichier précédemment enregistré Sérialiseur class pour effectuer la conversion en octets. sérialiseurs par défaut et peut être utilisé sans aucune configuration de notre part.
Sérialiseur personnalisé
pour plus de contrôle sur le processus de sérialisation, Kryo propose deux options, nous pouvons écrire la nôtre Sérialiseur class et enregistrez-le avec Kryo ou laissez la classe gérer la sérialisation par elle-même.
Voyons comment nous pouvons configurer Kryo pour l’utiliser dans notre application.
val conf = new SparkConf()
.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
.set("spark.kryoserializer.buffer.mb","24")
val sc = new SparkContext(conf)val sc = new SparkContext(conf)
_______________________
val spark = SparkSession.builder().appName(“KryoSerializerExample”)
.config(someConfig) .config(“spark.serializer”, “org.apache.spark.serializer.KryoSerializer”) .config(“spark.kryoserializer.buffer”, “1024k”) .config(“spark.kryoserializer.buffer.max”, “1024m”) .config(“spark.kryo.registrationRequired”, “true”)
.getOrCreate }
La taille de la mémoire tampon est utilisée pour contenir le le plus grand objet que vous allez sérialiser et il doit être suffisamment grand pour des performances optimales. KryoSérialiseur est une classe d’assistance fournie par l’étincelle pour faire face à Kryo. Nous créons une seule instance de KryoSerializer qui configure les tailles de tampon requises fournies dans la configuration.
Directives Databricks pour éviter les problèmes de sérialisation
Voici quelques-unes des directives élaborées par Databricks pour éviter les problèmes de sérialisation :
- Rendre l’objet/la classe sérialisable.
- déclarer l’instance dans la fonction lambda.
- Déclarez les fonctions à l’intérieur d’un objet autant que possible.
- Redéfinissez les variables fournies aux constructeurs de classe à l’intérieur des fonctions.
Ressources
https://spark.apache.org/docs/latest/tuning.html
https://github.com/EsotericSoftware/kryo