AVRO - Serializzazione

I dati vengono serializzati per due obiettivi:

  • Per l'archiviazione persistente

  • Per trasportare i dati sulla rete

Cos'è la serializzazione?

La serializzazione è il processo di traduzione delle strutture di dati o dello stato degli oggetti in forma binaria o testuale per trasportare i dati sulla rete o per archiviarli in una memoria persistente. Una volta che i dati sono stati trasportati sulla rete o recuperati dalla memoria persistente, devono essere nuovamente deserializzati. La serializzazione è definita comemarshalling e la deserializzazione è definita come unmarshalling.

Serializzazione in Java

Java fornisce un meccanismo, chiamato object serialization dove un oggetto può essere rappresentato come una sequenza di byte che include i dati dell'oggetto nonché le informazioni sul tipo di oggetto e sui tipi di dati memorizzati nell'oggetto.

Dopo che un oggetto serializzato è stato scritto in un file, può essere letto dal file e deserializzato. Ovvero, le informazioni sul tipo e i byte che rappresentano l'oggetto ei suoi dati possono essere utilizzati per ricreare l'oggetto in memoria.

ObjectInputStream e ObjectOutputStream le classi vengono utilizzate rispettivamente per serializzare e deserializzare un oggetto in Java.

Serializzazione in Hadoop

Generalmente nei sistemi distribuiti come Hadoop, viene utilizzato il concetto di serializzazione Interprocess Communication e Persistent Storage.

Comunicazione tra processi

  • Per stabilire la comunicazione interprocesso tra i nodi collegati in una rete, è stata utilizzata la tecnica RPC.

  • RPC ha utilizzato la serializzazione interna per convertire il messaggio in formato binario prima di inviarlo al nodo remoto tramite la rete. All'altra estremità il sistema remoto deserializza il flusso binario nel messaggio originale.

  • Il formato di serializzazione RPC deve essere il seguente:

    • Compact - Per utilizzare al meglio la larghezza di banda della rete, che è la risorsa più scarsa in un data center.

    • Fast - Poiché la comunicazione tra i nodi è cruciale nei sistemi distribuiti, il processo di serializzazione e deserializzazione dovrebbe essere veloce, producendo meno overhead.

    • Extensible - I protocolli cambiano nel tempo per soddisfare i nuovi requisiti, quindi dovrebbe essere semplice evolvere il protocollo in modo controllato per client e server.

    • Interoperable - Il formato del messaggio dovrebbe supportare i nodi scritti in lingue diverse.

Archiviazione persistente

Persistent Storage è una struttura di archiviazione digitale che non perde i dati con la perdita di alimentazione. File, cartelle, database sono esempi di archiviazione persistente.

Interfaccia scrivibile

Questa è l'interfaccia in Hadoop che fornisce metodi per la serializzazione e la deserializzazione. La tabella seguente descrive i metodi:

S.No. Metodi e descrizione
1

void readFields(DataInput in)

Questo metodo viene utilizzato per deserializzare i campi dell'oggetto specificato.

2

void write(DataOutput out)

Questo metodo viene utilizzato per serializzare i campi dell'oggetto specificato.

Interfaccia comparabile scrivibile

È la combinazione di Writable e Comparableinterfacce. Questa interfaccia ereditaWritable interfaccia di Hadoop così come Comparableinterfaccia di Java. Pertanto fornisce metodi per la serializzazione, la deserializzazione e il confronto dei dati.

S.No. Metodi e descrizione
1

int compareTo(class obj)

Questo metodo confronta l'oggetto corrente con l'oggetto dato obj.

Oltre a queste classi, Hadoop supporta una serie di classi wrapper che implementano l'interfaccia WritableComparable. Ogni classe racchiude un tipo primitivo Java. La gerarchia delle classi della serializzazione Hadoop è riportata di seguito:

Queste classi sono utili per serializzare vari tipi di dati in Hadoop. Ad esempio, consideriamo ilIntWritableclasse. Vediamo come viene usata questa classe per serializzare e deserializzare i dati in Hadoop.

Classe IntWritable

Questa classe implementa Writable, Comparable, e WritableComparableinterfacce. Avvolge un tipo di dati intero in esso. Questa classe fornisce metodi utilizzati per serializzare e deserializzare il tipo intero di dati.

Costruttori

S.No. Sommario
1 IntWritable()
2 IntWritable( int value)

Metodi

S.No. Sommario
1

int get()

Utilizzando questo metodo è possibile ottenere il valore intero presente nell'oggetto corrente.

2

void readFields(DataInput in)

Questo metodo viene utilizzato per deserializzare i dati nel file DataInput oggetto.

3

void set(int value)

Questo metodo viene utilizzato per impostare il valore della corrente IntWritable oggetto.

4

void write(DataOutput out)

Questo metodo viene utilizzato per serializzare i dati nell'oggetto corrente nel dato DataOutput oggetto.

Serializzazione dei dati in Hadoop

La procedura per serializzare il tipo intero di dati è discussa di seguito.

  • Istanziare IntWritable class inserendo un valore intero al suo interno.

  • Istanziare ByteArrayOutputStream classe.

  • Istanziare DataOutputStream class e passare l'oggetto di ByteArrayOutputStream classe ad esso.

  • Serializza il valore intero nell'oggetto IntWritable utilizzando write()metodo. Questo metodo richiede un oggetto della classe DataOutputStream.

  • I dati serializzati verranno memorizzati nell'oggetto array di byte che viene passato come parametro al file DataOutputStreamclasse al momento dell'istanziazione. Converti i dati nell'oggetto in array di byte.

Esempio

L'esempio seguente mostra come serializzare i dati di tipo intero in 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();
   }
}

Deserializzazione dei dati in Hadoop

La procedura per deserializzare il tipo intero di dati è discussa di seguito:

  • Istanziare IntWritable class inserendo un valore intero al suo interno.

  • Istanziare ByteArrayOutputStream classe.

  • Istanziare DataOutputStream class e passare l'oggetto di ByteArrayOutputStream classe ad esso.

  • Deserializza i dati nell'oggetto di DataInputStream utilizzando readFields() metodo della classe IntWritable.

  • I dati deserializzati verranno archiviati nell'oggetto della classe IntWritable. Puoi recuperare questi dati usandoget() metodo di questa classe.

Esempio

L'esempio seguente mostra come deserializzare i dati di tipo intero in 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());
   }
}

Vantaggio di Hadoop rispetto alla serializzazione Java

La serializzazione basata su scrivibili di Hadoop è in grado di ridurre il sovraccarico per la creazione di oggetti riutilizzando gli oggetti scrivibili, il che non è possibile con il framework di serializzazione nativo di Java.

Svantaggi della serializzazione Hadoop

Per serializzare i dati Hadoop, esistono due modi:

  • Puoi usare il file Writable classi, fornite dalla libreria nativa di Hadoop.

  • Puoi anche usare Sequence Files che memorizzano i dati in formato binario.

Lo svantaggio principale di questi due meccanismi è quello Writables e SequenceFiles hanno solo un'API Java e non possono essere scritti o letti in nessun altro linguaggio.

Pertanto nessuno dei file creati in Hadoop con i due meccanismi di cui sopra non può essere letto da nessun'altra terza lingua, il che rende Hadoop una scatola limitata. Per risolvere questo inconveniente, Doug Cutting ha creatoAvro, il quale è un language independent data structure.