AVRO - Guide rapide
Pour transférer des données sur un réseau ou pour son stockage persistant, vous devez sérialiser les données. Avant leserialization APIs fourni par Java et Hadoop, nous avons un utilitaire spécial, appelé Avro, une technique de sérialisation basée sur des schémas.
Ce didacticiel vous apprend à sérialiser et désérialiser les données à l'aide d'Avro. Avro fournit des bibliothèques pour divers langages de programmation. Dans ce didacticiel, nous présentons les exemples utilisant la bibliothèque Java.
Qu'est-ce qu'Avro?
Apache Avro est un système de sérialisation de données indépendant du langage. Il a été développé par Doug Cutting, le père de Hadoop. Étant donné que les classes inscriptibles Hadoop manquent de portabilité de langue, Avro devient très utile, car il traite des formats de données pouvant être traités par plusieurs langues. Avro est un outil privilégié pour sérialiser les données dans Hadoop.
Avro a un système basé sur des schémas. Un schéma indépendant du langage est associé à ses opérations de lecture et d'écriture. Avro sérialise les données qui ont un schéma intégré. Avro sérialise les données dans un format binaire compact, qui peut être désérialisé par n'importe quelle application.
Avro utilise le format JSON pour déclarer les structures de données. Actuellement, il prend en charge des langages tels que Java, C, C ++, C #, Python et Ruby.
Schémas Avro
Avro dépend fortement de son schema. Il permet à toutes les données d'être écrites sans connaissance préalable du schéma. Il sérialise rapidement et les données sérialisées qui en résultent sont de moindre taille. Le schéma est stocké avec les données Avro dans un fichier pour tout traitement ultérieur.
Dans RPC, le client et le serveur échangent des schémas pendant la connexion. Cet échange aide à la communication entre les mêmes champs nommés, les champs manquants, les champs supplémentaires, etc.
Les schémas Avro sont définis avec JSON qui simplifie son implémentation dans les langages avec des bibliothèques JSON.
Comme Avro, il existe d'autres mécanismes de sérialisation dans Hadoop tels que Sequence Files, Protocol Buffers, et Thrift.
Comparaison avec les tampons Thrift et Protocol
Thrift et Protocol Bufferssont les bibliothèques les plus compétentes avec Avro. Avro diffère de ces frameworks des manières suivantes -
Avro prend en charge les types dynamiques et statiques selon l'exigence. Protocol Buffers et Thrift utilisent des langages de définition d'interface (IDL) pour spécifier les schémas et leurs types. Ces IDL sont utilisés pour générer du code pour la sérialisation et la désérialisation.
Avro est construit dans l'écosystème Hadoop. Les tampons d'épargne et de protocole ne sont pas intégrés à l'écosystème Hadoop.
Contrairement à Thrift et Protocol Buffer, la définition de schéma d'Avro est en JSON et non dans un IDL propriétaire.
Propriété | Avro | Tampon d'économie et de protocole |
---|---|---|
Schéma dynamique | Oui | Non |
Intégré à Hadoop | Oui | Non |
Schéma en JSON | Oui | Non |
Pas besoin de compiler | Oui | Non |
Pas besoin de déclarer les identifiants | Oui | Non |
Bord de saignement | Oui | Non |
Caractéristiques d'Avro
Voici quelques-unes des principales caractéristiques d'Avro -
Avro est un language-neutral système de sérialisation des données.
Il peut être traité par de nombreux langages (actuellement C, C ++, C #, Java, Python et Ruby).
Avro crée un format structuré binaire qui est à la fois compressible et splittable. Par conséquent, il peut être utilisé efficacement comme entrée des travaux Hadoop MapReduce.
Avro fournit rich data structures. Par exemple, vous pouvez créer un enregistrement contenant un tableau, un type énuméré et un sous-enregistrement. Ces types de données peuvent être créés dans n'importe quelle langue, peuvent être traités dans Hadoop et les résultats peuvent être transmis à une troisième langue.
Avro schemas défini dans JSON, facilite l'implémentation dans les langages qui ont déjà des bibliothèques JSON.
Avro crée un fichier auto-descriptif nommé Avro Data File, dans lequel il stocke les données avec son schéma dans la section des métadonnées.
Avro est également utilisé dans les appels de procédure à distance (RPC). Pendant le RPC, le client et le serveur échangent des schémas lors de la négociation de connexion.
Fonctionnement général d'Avro
Pour utiliser Avro, vous devez suivre le flux de travail donné -
Step 1- Créez des schémas. Ici, vous devez concevoir le schéma Avro en fonction de vos données.
Step 2- Lisez les schémas dans votre programme. Cela se fait de deux manières -
By Generating a Class Corresponding to Schema- Compilez le schéma à l'aide d'Avro. Cela génère un fichier de classe correspondant au schéma
By Using Parsers Library - Vous pouvez lire directement le schéma à l'aide de la bibliothèque d'analyseurs.
Step 3 - Sérialiser les données à l'aide de l'API de sérialisation fournie pour Avro, qui se trouve dans le package org.apache.avro.specific.
Step 4 - Désérialiser les données à l'aide de l'API de désérialisation fournie pour Avro, qui se trouve dans le package org.apache.avro.specific.
Les données sont sérialisées pour deux objectifs -
Pour un stockage persistant
Pour transporter les données sur le réseau
Qu'est-ce que la sérialisation?
La sérialisation est le processus de traduction des structures de données ou de l'état des objets sous forme binaire ou textuelle pour transporter les données sur le réseau ou les stocker sur un stockage persistant. Une fois que les données sont transportées sur le réseau ou extraites du stockage persistant, elles doivent à nouveau être désérialisées. La sérialisation est appeléemarshalling et la désérialisation est appelée unmarshalling.
Sérialisation en Java
Java fournit un mécanisme, appelé object serialization où un objet peut être représenté comme une séquence d'octets qui inclut les données de l'objet ainsi que des informations sur le type de l'objet et les types de données stockées dans l'objet.
Une fois qu'un objet sérialisé est écrit dans un fichier, il peut être lu à partir du fichier et désérialisé. Autrement dit, les informations de type et les octets qui représentent l'objet et ses données peuvent être utilisés pour recréer l'objet en mémoire.
ObjectInputStream et ObjectOutputStream Les classes sont utilisées pour sérialiser et désérialiser un objet respectivement en Java.
Sérialisation dans Hadoop
Généralement dans les systèmes distribués comme Hadoop, le concept de sérialisation est utilisé pour Interprocess Communication et Persistent Storage.
Communication interprocessus
Pour établir la communication interprocessus entre les nœuds connectés dans un réseau, la technique RPC a été utilisée.
RPC a utilisé la sérialisation interne pour convertir le message au format binaire avant de l'envoyer au nœud distant via le réseau. À l'autre extrémité, le système distant désérialise le flux binaire dans le message d'origine.
Le format de sérialisation RPC doit être le suivant -
Compact - Utiliser au mieux la bande passante du réseau, qui est la ressource la plus rare dans un centre de données.
Fast - La communication entre les nœuds étant cruciale dans les systèmes distribués, le processus de sérialisation et de désérialisation devrait être rapide, produisant moins de frais généraux.
Extensible - Les protocoles changent au fil du temps pour répondre aux nouvelles exigences, il devrait donc être simple de faire évoluer le protocole de manière contrôlée pour les clients et les serveurs.
Interoperable - Le format de message doit prendre en charge les nœuds écrits dans différentes langues.
Stockage persistant
Le stockage persistant est une installation de stockage numérique qui ne perd pas ses données en cas de perte d'alimentation électrique. Les fichiers, dossiers, bases de données sont des exemples de stockage persistant.
Interface inscriptible
Il s'agit de l'interface dans Hadoop qui fournit des méthodes de sérialisation et de désérialisation. Le tableau suivant décrit les méthodes -
S.No. | Méthodes et description |
---|---|
1 | void readFields(DataInput in) Cette méthode est utilisée pour désérialiser les champs de l'objet donné. |
2 | void write(DataOutput out) Cette méthode est utilisée pour sérialiser les champs de l'objet donné. |
Interface comparable inscriptible
C'est la combinaison de Writable et Comparableles interfaces. Cette interface hériteWritable interface de Hadoop ainsi que Comparableinterface de Java. Par conséquent, il fournit des méthodes pour la sérialisation, la désérialisation et la comparaison des données.
S.No. | Méthodes et description |
---|---|
1 | int compareTo(class obj) Cette méthode compare l'objet actuel avec l'objet obj donné. |
En plus de ces classes, Hadoop prend en charge un certain nombre de classes wrapper qui implémentent l'interface WritableComparable. Chaque classe encapsule un type primitif Java. La hiérarchie des classes de la sérialisation Hadoop est donnée ci-dessous -
Ces classes sont utiles pour sérialiser divers types de données dans Hadoop. Par exemple, considérons leIntWritableclasse. Voyons comment cette classe est utilisée pour sérialiser et désérialiser les données dans Hadoop.
Classe IntWritable
Cette classe implémente Writable, Comparable, et WritableComparableles interfaces. Il enveloppe un type de données entier. Cette classe fournit des méthodes utilisées pour sérialiser et désérialiser le type entier de données.
Constructeurs
S.No. | Sommaire |
---|---|
1 | IntWritable() |
2 | IntWritable( int value) |
Méthodes
S.No. | Sommaire |
---|---|
1 | int get() En utilisant cette méthode, vous pouvez obtenir la valeur entière présente dans l'objet actuel. |
2 | void readFields(DataInput in) Cette méthode est utilisée pour désérialiser les données dans le DataInput objet. |
3 | void set(int value) Cette méthode est utilisée pour définir la valeur du courant IntWritable objet. |
4 | void write(DataOutput out) Cette méthode est utilisée pour sérialiser les données de l'objet courant vers le DataOutput objet. |
Sérialisation des données dans Hadoop
La procédure de sérialisation du type entier de données est décrite ci-dessous.
Instancier IntWritable classe en y enveloppant une valeur entière.
Instancier ByteArrayOutputStream classe.
Instancier DataOutputStream classe et passez l'objet de ByteArrayOutputStream classe à elle.
Sérialiser la valeur entière dans l'objet IntWritable à l'aide de write()méthode. Cette méthode nécessite un objet de la classe DataOutputStream.
Les données sérialisées seront stockées dans l'objet tableau d'octets qui est passé en paramètre au DataOutputStreamclasse au moment de l'instanciation. Convertissez les données de l'objet en tableau d'octets.
Exemple
L'exemple suivant montre comment sérialiser des données de type entier dans Hadoop -
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
public class Serialization {
public byte[] serialize() throws IOException{
//Instantiating the IntWritable object
IntWritable intwritable = new IntWritable(12);
//Instantiating ByteArrayOutputStream object
ByteArrayOutputStream byteoutputStream = new ByteArrayOutputStream();
//Instantiating DataOutputStream object
DataOutputStream dataOutputStream = new
DataOutputStream(byteoutputStream);
//Serializing the data
intwritable.write(dataOutputStream);
//storing the serialized object in bytearray
byte[] byteArray = byteoutputStream.toByteArray();
//Closing the OutputStream
dataOutputStream.close();
return(byteArray);
}
public static void main(String args[]) throws IOException{
Serialization serialization= new Serialization();
serialization.serialize();
System.out.println();
}
}
Désérialisation des données dans Hadoop
La procédure pour désérialiser le type entier de données est décrite ci-dessous -
Instancier IntWritable classe en y enveloppant une valeur entière.
Instancier ByteArrayOutputStream classe.
Instancier DataOutputStream classe et passez l'objet de ByteArrayOutputStream classe à elle.
Désérialiser les données dans l'objet de DataInputStream en utilisant readFields() méthode de la classe IntWritable.
Les données désérialisées seront stockées dans l'objet de la classe IntWritable. Vous pouvez récupérer ces données en utilisantget() méthode de cette classe.
Exemple
L'exemple suivant montre comment désérialiser les données de type entier dans Hadoop -
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import org.apache.hadoop.io.IntWritable;
public class Deserialization {
public void deserialize(byte[]byteArray) throws Exception{
//Instantiating the IntWritable class
IntWritable intwritable =new IntWritable();
//Instantiating ByteArrayInputStream object
ByteArrayInputStream InputStream = new ByteArrayInputStream(byteArray);
//Instantiating DataInputStream object
DataInputStream datainputstream=new DataInputStream(InputStream);
//deserializing the data in DataInputStream
intwritable.readFields(datainputstream);
//printing the serialized data
System.out.println((intwritable).get());
}
public static void main(String args[]) throws Exception {
Deserialization dese = new Deserialization();
dese.deserialize(new Serialization().serialize());
}
}
Avantage de Hadoop sur la sérialisation Java
La sérialisation basée sur Writable de Hadoop est capable de réduire la surcharge de création d'objets en réutilisant les objets Writable, ce qui n'est pas possible avec le framework de sérialisation natif de Java.
Inconvénients de la sérialisation Hadoop
Pour sérialiser les données Hadoop, il existe deux façons:
Vous pouvez utiliser le Writable classes, fournies par la bibliothèque native de Hadoop.
Vous pouvez aussi utiliser Sequence Files qui stockent les données au format binaire.
Le principal inconvénient de ces deux mécanismes est que Writables et SequenceFiles n'ont qu'une API Java et ils ne peuvent être écrits ou lus dans aucun autre langage.
Par conséquent, aucun des fichiers créés dans Hadoop avec les deux mécanismes ci-dessus ne peut être lu par un autre langage tiers, ce qui fait de Hadoop une boîte limitée. Pour remédier à cet inconvénient, Doug Cutting a crééAvro, qui est un language independent data structure.
La fondation logicielle Apache fournit à Avro diverses versions. Vous pouvez télécharger la version requise à partir des miroirs Apache. Voyons, comment configurer l'environnement pour travailler avec Avro -
Téléchargement d'Avro
Pour télécharger Apache Avro, procédez comme suit -
Ouvrez la page Web Apache.org . Vous verrez la page d'accueil d'Apache Avro comme indiqué ci-dessous -
Cliquez sur projet → versions. Vous obtiendrez une liste des versions.
Sélectionnez la dernière version qui vous mène à un lien de téléchargement.
mirror.nexcess est l'un des liens où vous pouvez trouver la liste de toutes les bibliothèques de différentes langues prises en charge par Avro, comme indiqué ci-dessous -
Vous pouvez sélectionner et télécharger la bibliothèque pour l'une des langues fournies. Dans ce tutoriel, nous utilisons Java. Téléchargez donc les fichiers jaravro-1.7.7.jar et avro-tools-1.7.7.jar.
Avro avec Eclipse
Pour utiliser Avro dans l'environnement Eclipse, vous devez suivre les étapes ci-dessous -
Step 1. Ouvrez l'éclipse.
Step 2. Créez un projet.
Step 3.Cliquez avec le bouton droit sur le nom du projet. Vous obtiendrez un menu contextuel.
Step 4. Cliquer sur Build Path. Cela vous mène à un autre menu contextuel.
Step 5. Cliquer sur Configure Build Path... Vous pouvez voir la fenêtre Propriétés de votre projet comme indiqué ci-dessous -
Step 6. Sous l'onglet bibliothèques, cliquez sur ADD EXternal JARs... bouton.
Step 7. Sélectionnez le fichier jar avro-1.77.jar vous avez téléchargé.
Step 8. Cliquer sur OK.
Avro avec Maven
Vous pouvez également intégrer la bibliothèque Avro à votre projet à l'aide de Maven. Vous trouverez ci-dessous le fichier pom.xml pour Avro.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Test</groupId>
<artifactId>Test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro-tools</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.0-beta9</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.0-beta9</version>
</dependency>
</dependencies>
</project>
Définition du chemin de classe
Pour travailler avec Avro dans un environnement Linux, téléchargez les fichiers jar suivants -
- avro-1.77.jar
- avro-tools-1.77.jar
- log4j-api-2.0-beta9.jar
- og4j-core-2.0.beta9.jar.
Copiez ces fichiers dans un dossier et définissez le chemin d'accès aux classes dans le dossier, dans le./bashrc fichier comme indiqué ci-dessous.
#class path for Avro
export CLASSPATH=$CLASSPATH://home/Hadoop/Avro_Work/jars/*
Avro, étant un utilitaire de sérialisation basé sur des schémas, accepte les schémas en entrée. En dépit de divers schémas disponibles, Avro suit ses propres normes de définition des schémas. Ces schémas décrivent les détails suivants -
- type de fichier (enregistrement par défaut)
- lieu d'enregistrement
- nom du dossier
- champs de l'enregistrement avec leurs types de données correspondants
À l'aide de ces schémas, vous pouvez stocker des valeurs sérialisées au format binaire en utilisant moins d'espace. Ces valeurs sont stockées sans aucune métadonnée.
Création de schémas Avro
Le schéma Avro est créé au format de document JavaScript Object Notation (JSON), qui est un format léger d'échange de données basé sur du texte. Il est créé de l'une des manières suivantes -
- Une chaîne JSON
- Un objet JSON
- Un tableau JSON
Example - L'exemple suivant montre un schéma, qui définit un document, sous l'espace de nom Tutorialspoint, avec le nom Employee, avec les champs name et age.
{
"type" : "record",
"namespace" : "Tutorialspoint",
"name" : "Employee",
"fields" : [
{ "name" : "Name" , "type" : "string" },
{ "name" : "Age" , "type" : "int" }
]
}
Dans cet exemple, vous pouvez observer qu'il y a quatre champs pour chaque enregistrement -
type - Ce champ se trouve sous le document ainsi que sous le champ nommé champs.
Dans le cas d'un document, il montre le type du document, généralement un enregistrement car il y a plusieurs champs.
Lorsqu'il s'agit d'un champ, le type décrit le type de données.
namespace - Ce champ décrit le nom de l'espace de noms dans lequel réside l'objet.
name - Ce champ se trouve sous le document ainsi que sous le champ nommé champs.
Dans le cas d'un document, il décrit le nom du schéma. Ce nom de schéma avec l'espace de noms identifie de manière unique le schéma dans le magasin (Namespace.schema name). Dans l'exemple ci-dessus, le nom complet du schéma sera Tutorialspoint.Employee.
Dans le cas des champs, il décrit le nom du champ.
Types de données primitifs d'Avro
Le schéma Avro a des types de données primitifs ainsi que des types de données complexes. Le tableau suivant décrit lesprimitive data types d'Avro -
Type de données | La description |
---|---|
nul | Null est un type sans valeur. |
int | Entier signé 32 bits. |
longue | Entier signé 64 bits. |
flotte | nombre à virgule flottante IEEE 754 simple précision (32 bits). |
double | nombre à virgule flottante IEEE 754 double précision (64 bits). |
octets | séquence d'octets non signés de 8 bits. |
chaîne | Séquence de caractères Unicode. |
Types de données complexes d'Avro
Outre les types de données primitifs, Avro fournit six types de données complexes, à savoir les enregistrements, les énumérations, les tableaux, les cartes, les unions et les fixes.
Record
Un type de données d'enregistrement dans Avro est une collection de plusieurs attributs. Il prend en charge les attributs suivants -
name - La valeur de ce champ contient le nom de l'enregistrement.
namespace - La valeur de ce champ contient le nom de l'espace de noms dans lequel l'objet est stocké.
type - La valeur de cet attribut contient soit le type du document (enregistrement), soit le type de données du champ dans le schéma.
fields - Ce champ contient un tableau JSON, qui contient la liste de tous les champs du schéma, chacun ayant des attributs de nom et de type.
Example
Ci-dessous est l'exemple d'un enregistrement.
{
" type " : "record",
" namespace " : "Tutorialspoint",
" name " : "Employee",
" fields " : [
{ "name" : " Name" , "type" : "string" },
{ "name" : "age" , "type" : "int" }
]
}
Enum
Une énumération est une liste d'éléments dans une collection, l'énumération Avro prend en charge les attributs suivants -
name - La valeur de ce champ contient le nom de l'énumération.
namespace - La valeur de ce champ contient la chaîne qui qualifie le nom de l'énumération.
symbols - La valeur de ce champ contient les symboles de l'énumération sous forme de tableau de noms.
Example
Ci-dessous, un exemple d'énumération.
{
"type" : "enum",
"name" : "Numbers",
"namespace": "data",
"symbols" : [ "ONE", "TWO", "THREE", "FOUR" ]
}
Tableaux
Ce type de données définit un champ de tableau ayant un seul élément d'attribut. Cet attribut d'éléments spécifie le type d'éléments dans le tableau.
Example
{ " type " : " array ", " items " : " int " }
Plans
Le type de données de carte est un tableau de paires clé-valeur, il organise les données sous forme de paires clé-valeur. La clé d'une carte Avro doit être une chaîne. Les valeurs d'une carte contiennent le type de données du contenu de la carte.
Example
{"type" : "map", "values" : "int"}
Les syndicats
Un type de données union est utilisé chaque fois que le champ a un ou plusieurs types de données. Ils sont représentés sous forme de tableaux JSON. Par exemple, si un champ peut être un entier ou nul, alors l'union est représentée par ["int", "null"].
Example
Vous trouverez ci-dessous un exemple de document utilisant des syndicats -
{
"type" : "record",
"namespace" : "tutorialspoint",
"name" : "empdetails ",
"fields" :
[
{ "name" : "experience", "type": ["int", "null"] }, { "name" : "age", "type": "int" }
]
}
Fixé
Ce type de données est utilisé pour déclarer un champ de taille fixe qui peut être utilisé pour stocker des données binaires. Il a un nom de champ et des données comme attributs. Name contient le nom du champ et la taille contient la taille du champ.
Example
{ "type" : "fixed" , "name" : "bdata", "size" : 1048576}
Dans le chapitre précédent, nous avons décrit le type d'entrée d'Avro, c'est-à-dire les schémas Avro. Dans ce chapitre, nous expliquerons les classes et les méthodes utilisées dans la sérialisation et la désérialisation des schémas Avro.
Classe SpecificDatumWriter
Cette classe appartient au package org.apache.avro.specific. Il met en œuvre leDatumWriter interface qui convertit les objets Java en un format sérialisé en mémoire.
Constructeur
S.No. | La description |
---|---|
1 | SpecificDatumWriter(Schema schema) |
Méthode
S.No. | La description |
---|---|
1 | SpecificData getSpecificData() Renvoie l'implémentation SpecificData utilisée par cet enregistreur. |
SpecificDatumReader, classe
Cette classe appartient au package org.apache.avro.specific. Il met en œuvre leDatumReader interface qui lit les données d'un schéma et détermine la représentation des données en mémoire. SpecificDatumReader est la classe qui prend en charge les classes java générées.
Constructeur
S.No. | La description |
---|---|
1 | SpecificDatumReader(Schema schema) Construisez où les schémas de l'écrivain et du lecteur sont les mêmes. |
Méthodes
S.No. | La description |
---|---|
1 | SpecificData getSpecificData() Renvoie le SpecificData contenu. |
2 | void setSchema(Schema actual) Cette méthode est utilisée pour définir le schéma de l'écrivain. |
DataFileWriter
Instancie DataFileWrite pour empclasse. Cette classe écrit une séquence d'enregistrements sérialisés de données conformes à un schéma, avec le schéma dans un fichier.
Constructeur
S.No. | La description |
---|---|
1 | DataFileWriter(DatumWriter<D> dout) |
Méthodes
S.Non | La description |
---|---|
1 | void append(D datum) Ajoute une donnée à un fichier. |
2 | DataFileWriter<D> appendTo(File file) Cette méthode est utilisée pour ouvrir un enregistreur en ajoutant à un fichier existant. |
Data FileReader
Cette classe fournit un accès aléatoire aux fichiers écrits avec DataFileWriter. Il hérite de la classeDataFileStream.
Constructeur
S.No. | La description |
---|---|
1 | DataFileReader(File file, DatumReader<D> reader)) |
Méthodes
S.No. | La description |
---|---|
1 | next() Lit la donnée suivante dans le fichier. |
2 | Boolean hasNext() Renvoie vrai si plus d'entrées restent dans ce fichier. |
Classe Schema.parser
Cette classe est un analyseur pour les schémas au format JSON. Il contient des méthodes pour analyser le schéma. Il appartient àorg.apache.avro paquet.
Constructeur
S.No. | La description |
---|---|
1 | Schema.Parser() |
Méthodes
S.No. | La description |
---|---|
1 | parse (File file) Analyse le schéma fourni dans le file. |
2 | parse (InputStream in) Analyse le schéma fourni dans le InputStream. |
3 | parse (String s) Analyse le schéma fourni dans le String. |
Interface GenricRecord
Cette interface fournit des méthodes pour accéder aux champs par nom ainsi que par index.
Méthodes
S.No. | La description |
---|---|
1 | Object get(String key) Renvoie la valeur d'un champ donné. |
2 | void put(String key, Object v) Définit la valeur d'un champ en fonction de son nom. |
Classe GenericData.Record
Constructeur
S.No. | La description |
---|---|
1 | GenericData.Record(Schema schema) |
Méthodes
S.No. | La description |
---|---|
1 | Object get(String key) Renvoie la valeur d'un champ du nom donné. |
2 | Schema getSchema() Renvoie le schéma de cette instance. |
3 | void put(int i, Object v) Définit la valeur d'un champ en fonction de sa position dans le schéma. |
4 | void put(String key, Object value) Définit la valeur d'un champ en fonction de son nom. |
On peut lire un schéma Avro dans le programme soit en générant une classe correspondant à un schéma soit en utilisant la bibliothèque d'analyseurs. Ce chapitre décrit comment lire le schémaby generating a class et Serializing les données en utilisant Avr.
Sérialisation en générant une classe
Pour sérialiser les données à l'aide d'Avro, suivez les étapes ci-dessous -
Écrivez un schéma Avro.
Compilez le schéma à l'aide de l'utilitaire Avro. Vous obtenez le code Java correspondant à ce schéma.
Remplissez le schéma avec les données.
Sérialisez-le à l'aide de la bibliothèque Avro.
Définition d'un schéma
Supposons que vous vouliez un schéma avec les détails suivants -
Field | Nom | id | âge | un salaire | adresse |
type | Chaîne | int | int | int | chaîne |
Créez un schéma Avro comme indiqué ci-dessous.
Enregistrez-le sous emp.avsc.
{
"namespace": "tutorialspoint.com",
"type": "record",
"name": "emp",
"fields": [
{"name": "name", "type": "string"},
{"name": "id", "type": "int"},
{"name": "salary", "type": "int"},
{"name": "age", "type": "int"},
{"name": "address", "type": "string"}
]
}
Compiler le schéma
Après avoir créé un schéma Avro, vous devez compiler le schéma créé à l'aide des outils Avro. avro-tools-1.7.7.jar est le pot contenant les outils.
Syntaxe pour compiler un schéma Avro
java -jar <path/to/avro-tools-1.7.7.jar> compile schema <path/to/schema-file> <destination-folder>
Ouvrez le terminal dans le dossier de départ.
Créez un nouveau répertoire pour travailler avec Avro comme indiqué ci-dessous -
$ mkdir Avro_Work
Dans le répertoire nouvellement créé, créez trois sous-répertoires -
Premier nommé schema, pour placer le schéma.
Deuxième nommé with_code_gen, pour placer le code généré.
Troisième nommé jars, pour placer les fichiers jar.
$ mkdir schema
$ mkdir with_code_gen
$ mkdir jars
La capture d'écran suivante montre comment votre Avro_work Le dossier doit ressembler à après avoir créé tous les répertoires.
Maintenant /home/Hadoop/Avro_work/jars/avro-tools-1.7.7.jar est le chemin du répertoire dans lequel vous avez téléchargé le fichier avro-tools-1.7.7.jar.
/home/Hadoop/Avro_work/schema/ est le chemin du répertoire dans lequel votre fichier de schéma emp.avsc est stocké.
/home/Hadoop/Avro_work/with_code_gen est le répertoire dans lequel vous souhaitez stocker les fichiers de classe générés.
Maintenant, compilez le schéma comme indiqué ci-dessous -
$ java -jar /home/Hadoop/Avro_work/jars/avro-tools-1.7.7.jar compile schema /home/Hadoop/Avro_work/schema/emp.avsc /home/Hadoop/Avro/with_code_gen
Après la compilation, un package en fonction de l'espace de nom du schéma est créé dans le répertoire de destination. Dans ce package, le code source Java avec le nom du schéma est créé. Ce code source généré est le code Java du schéma donné qui peut être utilisé directement dans les applications.
Par exemple, dans ce cas, un package / dossier, nommé tutorialspoint est créé qui contient un autre dossier nommé com (puisque l'espace de nom est tutorialspoint.com) et à l'intérieur de celui-ci, vous pouvez observer le fichier généré emp.java. L'instantané suivant montreemp.java -
Cette classe est utile pour créer des données selon le schéma.
La classe générée contient -
- Constructeur par défaut et constructeur paramétré qui acceptent toutes les variables du schéma.
- Les méthodes setter et getter pour toutes les variables du schéma.
- Get () méthode qui renvoie le schéma.
- Méthodes du constructeur.
Création et sérialisation des données
Tout d'abord, copiez le fichier java généré utilisé dans ce projet dans le répertoire courant ou importez-le d'où il se trouve.
Nous pouvons maintenant écrire un nouveau fichier Java et instancier la classe dans le fichier généré (emp) pour ajouter les données des employés au schéma.
Voyons la procédure pour créer des données selon le schéma à l'aide d'apache Avro.
Étape 1
Instancier le généré emp classe.
emp e1=new emp( );
Étape 2
À l'aide des méthodes de setter, insérez les données du premier employé. Par exemple, nous avons créé les coordonnées de l'employé nommé Omar.
e1.setName("omar");
e1.setAge(21);
e1.setSalary(30000);
e1.setAddress("Hyderabad");
e1.setId(001);
De même, remplissez tous les détails de l'employé à l'aide des méthodes de définition.
Étape 3
Créer un objet de DatumWriter interface utilisant le SpecificDatumWriterclasse. Cela convertit les objets Java en un format sérialisé en mémoire. L'exemple suivant instancieSpecificDatumWriter objet de classe pour emp classe.
DatumWriter<emp> empDatumWriter = new SpecificDatumWriter<emp>(emp.class);
Étape 4
Instancier DataFileWriter pour empclasse. Cette classe écrit une séquence d'enregistrements sérialisés de données conformes à un schéma, avec le schéma lui-même, dans un fichier. Cette classe nécessite leDatumWriter object, en tant que paramètre du constructeur.
DataFileWriter<emp> empFileWriter = new DataFileWriter<emp>(empDatumWriter);
Étape 5
Ouvrez un nouveau fichier pour stocker les données correspondant au schéma donné en utilisant create()méthode. Cette méthode requiert le schéma et le chemin du fichier dans lequel les données doivent être stockées en tant que paramètres.
Dans l'exemple suivant, le schéma est transmis à l'aide de getSchema() méthode, et le fichier de données est stocké dans le chemin - /home/Hadoop/Avro/serialized_file/emp.avro.
empFileWriter.create(e1.getSchema(),new File("/home/Hadoop/Avro/serialized_file/emp.avro"));
Étape 6
Ajoutez tous les enregistrements créés au fichier en utilisant append() méthode comme indiqué ci-dessous -
empFileWriter.append(e1);
empFileWriter.append(e2);
empFileWriter.append(e3);
Exemple - Sérialisation en générant une classe
Le programme complet suivant montre comment sérialiser des données dans un fichier à l'aide d'Apache Avro -
import java.io.File;
import java.io.IOException;
import org.apache.avro.file.DataFileWriter;
import org.apache.avro.io.DatumWriter;
import org.apache.avro.specific.SpecificDatumWriter;
public class Serialize {
public static void main(String args[]) throws IOException{
//Instantiating generated emp class
emp e1=new emp();
//Creating values according the schema
e1.setName("omar");
e1.setAge(21);
e1.setSalary(30000);
e1.setAddress("Hyderabad");
e1.setId(001);
emp e2=new emp();
e2.setName("ram");
e2.setAge(30);
e2.setSalary(40000);
e2.setAddress("Hyderabad");
e2.setId(002);
emp e3=new emp();
e3.setName("robbin");
e3.setAge(25);
e3.setSalary(35000);
e3.setAddress("Hyderabad");
e3.setId(003);
//Instantiate DatumWriter class
DatumWriter<emp> empDatumWriter = new SpecificDatumWriter<emp>(emp.class);
DataFileWriter<emp> empFileWriter = new DataFileWriter<emp>(empDatumWriter);
empFileWriter.create(e1.getSchema(), new File("/home/Hadoop/Avro_Work/with_code_gen/emp.avro"));
empFileWriter.append(e1);
empFileWriter.append(e2);
empFileWriter.append(e3);
empFileWriter.close();
System.out.println("data successfully serialized");
}
}
Parcourez le répertoire dans lequel le code généré est placé. Dans ce cas, àhome/Hadoop/Avro_work/with_code_gen.
In Terminal −
$ cd home/Hadoop/Avro_work/with_code_gen/
In GUI −
Maintenant, copiez et enregistrez le programme ci-dessus dans le fichier nommé Serialize.java
Compilez et exécutez-le comme indiqué ci-dessous -
$ javac Serialize.java
$ java Serialize
Production
data successfully serialized
Si vous vérifiez le chemin indiqué dans le programme, vous pouvez trouver le fichier sérialisé généré comme indiqué ci-dessous.
Comme décrit précédemment, on peut lire un schéma Avro dans un programme soit en générant une classe correspondant au schéma soit en utilisant la bibliothèque d'analyseurs. Ce chapitre décrit comment lire le schémaby generating a class et Deserialize les données en utilisant Avro.
Désérialisation en générant une classe
Les données sérialisées sont stockées dans le fichier emp.avro. Vous pouvez le désérialiser et le lire à l'aide d'Avro.
Suivez la procédure ci-dessous pour désérialiser les données sérialisées d'un fichier.
Étape 1
Créer un objet de DatumReader interface utilisant SpecificDatumReader classe.
DatumReader<emp>empDatumReader = new SpecificDatumReader<emp>(emp.class);
Étape 2
Instancier DataFileReader pour empclasse. Cette classe lit les données sérialisées à partir d'un fichier. Cela nécessite leDataumeader objet et chemin du fichier dans lequel les données sérialisées existent, en tant que paramètres du constructeur.
DataFileReader<emp> dataFileReader = new DataFileReader(new File("/path/to/emp.avro"), empDatumReader);
Étape 3
Imprimez les données désérialisées, en utilisant les méthodes de DataFileReader.
le hasNext() La méthode retournera un booléen s'il y a des éléments dans le Reader.
le next() méthode de DataFileReader renvoie les données dans le Reader.
while(dataFileReader.hasNext()){
em=dataFileReader.next(em);
System.out.println(em);
}
Exemple - Désérialisation en générant une classe
Le programme complet suivant montre comment désérialiser les données d'un fichier à l'aide d'Avro.
import java.io.File;
import java.io.IOException;
import org.apache.avro.file.DataFileReader;
import org.apache.avro.io.DatumReader;
import org.apache.avro.specific.SpecificDatumReader;
public class Deserialize {
public static void main(String args[]) throws IOException{
//DeSerializing the objects
DatumReader<emp> empDatumReader = new SpecificDatumReader<emp>(emp.class);
//Instantiating DataFileReader
DataFileReader<emp> dataFileReader = new DataFileReader<emp>(new
File("/home/Hadoop/Avro_Work/with_code_genfile/emp.avro"), empDatumReader);
emp em=null;
while(dataFileReader.hasNext()){
em=dataFileReader.next(em);
System.out.println(em);
}
}
}
Naviguez dans le répertoire où le code généré est placé. Dans ce cas, àhome/Hadoop/Avro_work/with_code_gen.
$ cd home/Hadoop/Avro_work/with_code_gen/
Maintenant, copiez et enregistrez le programme ci-dessus dans le fichier nommé DeSerialize.java. Compilez et exécutez-le comme indiqué ci-dessous -
$ javac Deserialize.java
$ java Deserialize
Production
{"name": "omar", "id": 1, "salary": 30000, "age": 21, "address": "Hyderabad"}
{"name": "ram", "id": 2, "salary": 40000, "age": 30, "address": "Hyderabad"}
{"name": "robbin", "id": 3, "salary": 35000, "age": 25, "address": "Hyderabad"}
On peut lire un schéma Avro dans un programme soit en générant une classe correspondant à un schéma soit en utilisant la bibliothèque d'analyseurs. Dans Avro, les données sont toujours stockées avec leur schéma correspondant. Par conséquent, nous pouvons toujours lire un schéma sans génération de code.
Ce chapitre décrit comment lire le schéma by using parsers library et à serialize les données en utilisant Avro.
Sérialisation à l'aide de la bibliothèque d'analyseurs
Pour sérialiser les données, nous devons lire le schéma, créer des données selon le schéma et sérialiser le schéma à l'aide de l'API Avro. La procédure suivante sérialise les données sans générer de code -
Étape 1
Tout d'abord, lisez le schéma à partir du fichier. Pour ce faire, utilisezSchema.Parserclasse. Cette classe fournit des méthodes pour analyser le schéma dans différents formats.
Instancier le Schema.Parser class en passant le chemin du fichier où le schéma est stocké.
Schema schema = new Schema.Parser().parse(new File("/path/to/emp.avsc"));
Étape 2
Créer l'objet de GenericRecord interface, en instanciant GenericData.Recordclasse comme indiqué ci-dessous. Passez l'objet de schéma créé ci-dessus à son constructeur.
GenericRecord e1 = new GenericData.Record(schema);
Étape 3
Insérez les valeurs dans le schéma à l'aide du put() méthode de la GenericData classe.
e1.put("name", "ramu");
e1.put("id", 001);
e1.put("salary",30000);
e1.put("age", 25);
e1.put("address", "chennai");
Étape 4
Créer un objet de DatumWriter interface utilisant le SpecificDatumWriterclasse. Il convertit les objets Java en un format sérialisé en mémoire. L'exemple suivant instancieSpecificDatumWriter objet de classe pour emp classe -
DatumWriter<emp> empDatumWriter = new SpecificDatumWriter<emp>(emp.class);
Étape 5
Instancier DataFileWriter pour empclasse. Cette classe écrit des enregistrements sérialisés de données conformes à un schéma, avec le schéma lui-même, dans un fichier. Cette classe nécessite leDatumWriter object, en tant que paramètre du constructeur.
DataFileWriter<emp> dataFileWriter = new DataFileWriter<emp>(empDatumWriter);
Étape 6
Ouvrez un nouveau fichier pour stocker les données correspondant au schéma donné en utilisant create()méthode. Cette méthode requiert le schéma et le chemin du fichier dans lequel les données doivent être stockées en tant que paramètres.
Dans l'exemple ci-dessous, le schéma est passé en utilisant getSchema() méthode et le fichier de données est stocké dans le chemin
/home/Hadoop/Avro/serialized_file/emp.avro.
empFileWriter.create(e1.getSchema(), new
File("/home/Hadoop/Avro/serialized_file/emp.avro"));
Étape 7
Ajoutez tous les enregistrements créés au fichier en utilisant append( ) méthode comme indiqué ci-dessous.
empFileWriter.append(e1);
empFileWriter.append(e2);
empFileWriter.append(e3);
Exemple - Sérialisation à l'aide d'analyseurs
Le programme complet suivant montre comment sérialiser les données à l'aide d'analyseurs -
import java.io.File;
import java.io.IOException;
import org.apache.avro.Schema;
import org.apache.avro.file.DataFileWriter;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericDatumWriter;
import org.apache.avro.generic.GenericRecord;
import org.apache.avro.io.DatumWriter;
public class Seriali {
public static void main(String args[]) throws IOException{
//Instantiating the Schema.Parser class.
Schema schema = new Schema.Parser().parse(new File("/home/Hadoop/Avro/schema/emp.avsc"));
//Instantiating the GenericRecord class.
GenericRecord e1 = new GenericData.Record(schema);
//Insert data according to schema
e1.put("name", "ramu");
e1.put("id", 001);
e1.put("salary",30000);
e1.put("age", 25);
e1.put("address", "chenni");
GenericRecord e2 = new GenericData.Record(schema);
e2.put("name", "rahman");
e2.put("id", 002);
e2.put("salary", 35000);
e2.put("age", 30);
e2.put("address", "Delhi");
DatumWriter<GenericRecord> datumWriter = new GenericDatumWriter<GenericRecord>(schema);
DataFileWriter<GenericRecord> dataFileWriter = new DataFileWriter<GenericRecord>(datumWriter);
dataFileWriter.create(schema, new File("/home/Hadoop/Avro_work/without_code_gen/mydata.txt"));
dataFileWriter.append(e1);
dataFileWriter.append(e2);
dataFileWriter.close();
System.out.println(“data successfully serialized”);
}
}
Naviguez dans le répertoire où le code généré est placé. Dans ce cas, àhome/Hadoop/Avro_work/without_code_gen.
$ cd home/Hadoop/Avro_work/without_code_gen/
Maintenant, copiez et enregistrez le programme ci-dessus dans le fichier nommé Serialize.java. Compilez et exécutez-le comme indiqué ci-dessous -
$ javac Serialize.java
$ java Serialize
Production
data successfully serialized
Si vous vérifiez le chemin indiqué dans le programme, vous pouvez trouver le fichier sérialisé généré comme indiqué ci-dessous.
Comme mentionné précédemment, on peut lire un schéma Avro dans un programme soit en générant une classe correspondant à un schéma soit en utilisant la bibliothèque d'analyseurs. Dans Avro, les données sont toujours stockées avec leur schéma correspondant. Par conséquent, nous pouvons toujours lire un article sérialisé sans génération de code.
Ce chapitre décrit comment lire le schéma using parsers library et Deserializing les données en utilisant Avro.
Désérialisation à l'aide de la bibliothèque d'analyseurs
Les données sérialisées sont stockées dans le fichier mydata.txt. Vous pouvez le désérialiser et le lire à l'aide d'Avro.
Suivez la procédure ci-dessous pour désérialiser les données sérialisées d'un fichier.
Étape 1
Tout d'abord, lisez le schéma à partir du fichier. Pour ce faire, utilisezSchema.Parserclasse. Cette classe fournit des méthodes pour analyser le schéma dans différents formats.
Instancier le Schema.Parser class en passant le chemin du fichier où le schéma est stocké.
Schema schema = new Schema.Parser().parse(new File("/path/to/emp.avsc"));
Étape 2
Créer un objet de DatumReader interface utilisant SpecificDatumReader classe.
DatumReader<emp>empDatumReader = new SpecificDatumReader<emp>(emp.class);
Étape 3
Instancier DataFileReaderclasse. Cette classe lit les données sérialisées à partir d'un fichier. Cela nécessite leDatumReader objet et chemin du fichier où les données sérialisées existent, en tant que paramètres du constructeur.
DataFileReader<GenericRecord> dataFileReader = new DataFileReader<GenericRecord>(new File("/path/to/mydata.txt"), datumReader);
Étape 4
Imprimez les données désérialisées, en utilisant les méthodes de DataFileReader.
le hasNext() renvoie un booléen s'il y a des éléments dans le Reader.
le next() méthode de DataFileReader renvoie les données dans le Reader.
while(dataFileReader.hasNext()){
em=dataFileReader.next(em);
System.out.println(em);
}
Exemple - Désérialisation à l'aide de la bibliothèque d'analyseurs
Le programme complet suivant montre comment désérialiser les données sérialisées à l'aide de la bibliothèque Parsers -
public class Deserialize {
public static void main(String args[]) throws Exception{
//Instantiating the Schema.Parser class.
Schema schema = new Schema.Parser().parse(new File("/home/Hadoop/Avro/schema/emp.avsc"));
DatumReader<GenericRecord> datumReader = new GenericDatumReader<GenericRecord>(schema);
DataFileReader<GenericRecord> dataFileReader = new DataFileReader<GenericRecord>(new File("/home/Hadoop/Avro_Work/without_code_gen/mydata.txt"), datumReader);
GenericRecord emp = null;
while (dataFileReader.hasNext()) {
emp = dataFileReader.next(emp);
System.out.println(emp);
}
System.out.println("hello");
}
}
Naviguez dans le répertoire où le code généré est placé. Dans ce cas, c'est àhome/Hadoop/Avro_work/without_code_gen.
$ cd home/Hadoop/Avro_work/without_code_gen/
Maintenant, copiez et enregistrez le programme ci-dessus dans le fichier nommé DeSerialize.java. Compilez et exécutez-le comme indiqué ci-dessous -
$ javac Deserialize.java
$ java Deserialize
Production
{"name": "ramu", "id": 1, "salary": 30000, "age": 25, "address": "chennai"}
{"name": "rahman", "id": 2, "salary": 35000, "age": 30, "address": "Delhi"}