AVRO - Serialización

Los datos se serializan para dos objetivos:

  • Para almacenamiento persistente

  • Para transportar los datos a través de la red

¿Qué es la serialización?

La serialización es el proceso de traducir las estructuras de datos o el estado de los objetos en forma binaria o textual para transportar los datos a través de la red o para almacenarlos en algún almacenamiento persistente. Una vez que los datos se transportan a través de la red o se recuperan del almacenamiento persistente, es necesario volver a deserializarlos. La serialización se denominamarshalling y la deserialización se denomina unmarshalling.

Serialización en Java

Java proporciona un mecanismo, llamado object serialization donde un objeto se puede representar como una secuencia de bytes que incluye los datos del objeto, así como información sobre el tipo de objeto y los tipos de datos almacenados en el objeto.

Una vez que un objeto serializado se escribe en un archivo, se puede leer desde el archivo y deserializar. Es decir, la información de tipo y los bytes que representan el objeto y sus datos se pueden usar para recrear el objeto en la memoria.

ObjectInputStream y ObjectOutputStream las clases se utilizan para serializar y deserializar un objeto respectivamente en Java.

Serialización en Hadoop

Generalmente en sistemas distribuidos como Hadoop, el concepto de serialización se usa para Interprocess Communication y Persistent Storage.

Comunicación entre procesos

  • Para establecer la comunicación entre procesos entre los nodos conectados en una red, se utilizó la técnica RPC.

  • RPC utilizó la serialización interna para convertir el mensaje en formato binario antes de enviarlo al nodo remoto a través de la red. En el otro extremo, el sistema remoto deserializa el flujo binario en el mensaje original.

  • El formato de serialización de RPC debe ser el siguiente:

    • Compact - Hacer el mejor uso del ancho de banda de la red, que es el recurso más escaso en un centro de datos.

    • Fast - Dado que la comunicación entre los nodos es crucial en los sistemas distribuidos, el proceso de serialización y deserialización debe ser rápido y producir menos gastos generales.

    • Extensible - Los protocolos cambian con el tiempo para cumplir con los nuevos requisitos, por lo que debería ser sencillo evolucionar el protocolo de manera controlada para clientes y servidores.

    • Interoperable - El formato del mensaje debe admitir los nodos que están escritos en diferentes idiomas.

Almacenamiento persistente

El almacenamiento persistente es una instalación de almacenamiento digital que no pierde sus datos con la pérdida de la fuente de alimentación. Archivos, carpetas, bases de datos son ejemplos de almacenamiento persistente.

Interfaz de escritura

Esta es la interfaz en Hadoop que proporciona métodos para serialización y deserialización. La siguiente tabla describe los métodos:

S.No. Métodos y descripción
1

void readFields(DataInput in)

Este método se utiliza para deserializar los campos del objeto dado.

2

void write(DataOutput out)

Este método se utiliza para serializar los campos del objeto dado.

Interfaz comparable escribible

Es la combinación de Writable y Comparableinterfaces. Esta interfaz heredaWritable interfaz de Hadoop así como Comparableinterfaz de Java. Por lo tanto, proporciona métodos para la serialización, deserialización y comparación de datos.

S.No. Métodos y descripción
1

int compareTo(class obj)

Este método compara el objeto actual con el objeto dado obj.

Además de estas clases, Hadoop admite una serie de clases contenedoras que implementan la interfaz WritableComparable. Cada clase envuelve un tipo primitivo de Java. La jerarquía de clases de la serialización de Hadoop se da a continuación:

Estas clases son útiles para serializar varios tipos de datos en Hadoop. Por ejemplo, consideremos elIntWritableclase. Veamos cómo se usa esta clase para serializar y deserializar los datos en Hadoop.

Clase IntWritable

Esta clase implementa Writable, Comparable, y WritableComparableinterfaces. Envuelve un tipo de datos entero en él. Esta clase proporciona métodos que se utilizan para serializar y deserializar tipos de datos enteros.

Constructores

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

Métodos

S.No. Resumen
1

int get()

Con este método, puede obtener el valor entero presente en el objeto actual.

2

void readFields(DataInput in)

Este método se utiliza para deserializar los datos en el DataInput objeto.

3

void set(int value)

Este método se utiliza para establecer el valor de la corriente IntWritable objeto.

4

void write(DataOutput out)

Este método se utiliza para serializar los datos en el objeto actual a la dada DataOutput objeto.

Serializar los datos en Hadoop

El procedimiento para serializar el tipo de datos enteros se analiza a continuación.

  • Instanciar IntWritable clase envolviendo un valor entero en ella.

  • Instanciar ByteArrayOutputStream clase.

  • Instanciar DataOutputStream class y pasar el objeto de ByteArrayOutputStream clase a eso.

  • Serialice el valor entero en el objeto IntWritable usando write()método. Este método necesita un objeto de la clase DataOutputStream.

  • Los datos serializados se almacenarán en el objeto de matriz de bytes que se pasa como parámetro al DataOutputStreamclass en el momento de la instanciación. Convierta los datos del objeto en una matriz de bytes.

Ejemplo

El siguiente ejemplo muestra cómo serializar datos de tipo entero en 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();
   }
}

Deserializar los datos en Hadoop

El procedimiento para deserializar el tipo de datos enteros se analiza a continuación:

  • Instanciar IntWritable clase envolviendo un valor entero en ella.

  • Instanciar ByteArrayOutputStream clase.

  • Instanciar DataOutputStream class y pasar el objeto de ByteArrayOutputStream clase a eso.

  • Deserializar los datos en el objeto de DataInputStream utilizando readFields() método de la clase IntWritable.

  • Los datos deserializados se almacenarán en el objeto de la clase IntWritable. Puede recuperar estos datos usandoget() método de esta clase.

Ejemplo

El siguiente ejemplo muestra cómo deserializar los datos de tipo entero en 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());
   }
}

Ventaja de Hadoop sobre la serialización de Java

La serialización basada en escritura de Hadoop es capaz de reducir la sobrecarga de creación de objetos al reutilizar los objetos de escritura, lo que no es posible con el marco de serialización nativo de Java.

Desventajas de la serialización de Hadoop

Para serializar datos de Hadoop, hay dos formas:

  • Puedes usar el Writable clases, proporcionadas por la biblioteca nativa de Hadoop.

  • También puedes usar Sequence Files que almacenan los datos en formato binario.

El principal inconveniente de estos dos mecanismos es que Writables y SequenceFiles tienen solo una API de Java y no se pueden escribir ni leer en ningún otro idioma.

Por lo tanto, ninguno de los archivos creados en Hadoop con los dos mecanismos anteriores no se pueden leer en ningún otro tercer idioma, lo que hace que Hadoop sea una caja limitada. Para solucionar este inconveniente, Doug Cutting creóAvro, el cual es un language independent data structure.