AVRO - Serialização

Os dados são serializados para dois objetivos -

  • Para armazenamento persistente

  • Para transportar os dados pela rede

O que é serialização?

A serialização é o processo de traduzir estruturas de dados ou estado de objetos em forma binária ou textual para transportar os dados pela rede ou para armazenar em algum armazenamento persistente. Depois que os dados são transportados pela rede ou recuperados do armazenamento persistente, eles precisam ser desserializados novamente. A serialização é denominada comomarshalling e a desserialização é denominada como unmarshalling.

Serialização em Java

Java fornece um mecanismo, chamado object serialization onde um objeto pode ser representado como uma sequência de bytes que inclui os dados do objeto, bem como informações sobre o tipo do objeto e os tipos de dados armazenados no objeto.

Depois que um objeto serializado é gravado em um arquivo, ele pode ser lido do arquivo e desserializado. Ou seja, as informações de tipo e bytes que representam o objeto e seus dados podem ser usados ​​para recriar o objeto na memória.

ObjectInputStream e ObjectOutputStream classes são usadas para serializar e desserializar um objeto respectivamente em Java.

Serialização em Hadoop

Geralmente em sistemas distribuídos como Hadoop, o conceito de serialização é usado para Interprocess Communication e Persistent Storage.

Comunicação entre processos

  • Para estabelecer a comunicação entre processos entre os nós conectados em uma rede, foi utilizada a técnica RPC.

  • O RPC usou a serialização interna para converter a mensagem em formato binário antes de enviá-la ao nó remoto pela rede. Na outra extremidade, o sistema remoto desserializa o fluxo binário na mensagem original.

  • O formato de serialização RPC deve ser o seguinte -

    • Compact - Fazer o melhor uso da largura de banda da rede, que é o recurso mais escasso em um data center.

    • Fast - Como a comunicação entre os nós é crucial em sistemas distribuídos, o processo de serialização e desserialização deve ser rápido, produzindo menos overhead.

    • Extensible - Os protocolos mudam com o tempo para atender a novos requisitos, portanto, deve ser simples evoluir o protocolo de uma maneira controlada para clientes e servidores.

    • Interoperable - O formato da mensagem deve suportar os nós que são escritos em diferentes idiomas.

Armazenamento persistente

O Persistent Storage é uma instalação de armazenamento digital que não perde seus dados com a perda de alimentação. Arquivos, pastas, bancos de dados são exemplos de armazenamento persistente.

Interface gravável

Esta é a interface no Hadoop que fornece métodos para serialização e desserialização. A tabela a seguir descreve os métodos -

S.No. Métodos e Descrição
1

void readFields(DataInput in)

Este método é usado para desserializar os campos de um determinado objeto.

2

void write(DataOutput out)

Este método é usado para serializar os campos de um determinado objeto.

Interface gravável comparável

É a combinação de Writable e Comparableinterfaces. Esta interface herdaWritable interface do Hadoop, bem como Comparableinterface de Java. Portanto, ele fornece métodos para serialização, desserialização e comparação de dados.

S.No. Métodos e Descrição
1

int compareTo(class obj)

Este método compara o objeto atual com o objeto fornecido obj.

Além dessas classes, o Hadoop oferece suporte a várias classes de wrapper que implementam a interface WritableComparable. Cada classe envolve um tipo primitivo Java. A hierarquia de classes de serialização do Hadoop é fornecida abaixo -

Essas classes são úteis para serializar vários tipos de dados no Hadoop. Por exemplo, vamos considerar oIntWritableclasse. Vamos ver como essa classe é usada para serializar e desserializar os dados no Hadoop.

Classe IntWritable

Esta classe implementa Writable, Comparable, e WritableComparableinterfaces. Ele envolve um tipo de dados inteiro nele. Esta classe fornece métodos usados ​​para serializar e desserializar tipos de dados inteiros.

Construtores

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

Métodos

S.No. Resumo
1

int get()

Usando este método, você pode obter o valor inteiro presente no objeto atual.

2

void readFields(DataInput in)

Este método é usado para desserializar os dados no dado DataInput objeto.

3

void set(int value)

Este método é usado para definir o valor da corrente IntWritable objeto.

4

void write(DataOutput out)

Este método é usado para serializar os dados no objeto atual para o dado DataOutput objeto.

Serializando os dados no Hadoop

O procedimento para serializar o tipo inteiro de dados é discutido abaixo.

  • Instanciar IntWritable classe envolvendo um valor inteiro nela.

  • Instanciar ByteArrayOutputStream classe.

  • Instanciar DataOutputStream classe e passar o objeto de ByteArrayOutputStream classe para isso.

  • Serializar o valor inteiro no objeto IntWritable usando write()método. Este método precisa de um objeto da classe DataOutputStream.

  • Os dados serializados serão armazenados no objeto de matriz de bytes que é passado como parâmetro para o DataOutputStreamclasse no momento da instanciação. Converta os dados do objeto em uma matriz de bytes.

Exemplo

O exemplo a seguir mostra como serializar dados do tipo inteiro no 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();
   }
}

Desserializando os dados no Hadoop

O procedimento para desserializar o tipo inteiro de dados é discutido abaixo -

  • Instanciar IntWritable classe envolvendo um valor inteiro nela.

  • Instanciar ByteArrayOutputStream classe.

  • Instanciar DataOutputStream classe e passar o objeto de ByteArrayOutputStream classe para isso.

  • Desserialize os dados no objeto de DataInputStream usando readFields() método da classe IntWritable.

  • Os dados desserializados serão armazenados no objeto da classe IntWritable. Você pode recuperar esses dados usandoget() método desta classe.

Exemplo

O exemplo a seguir mostra como desserializar os dados do tipo inteiro no 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());
   }
}

Vantagem do Hadoop sobre a serialização Java

A serialização baseada em gravável do Hadoop é capaz de reduzir a sobrecarga de criação de objeto ao reutilizar os objetos graváveis, o que não é possível com a estrutura de serialização nativa do Java.

Desvantagens da serialização Hadoop

Para serializar dados do Hadoop, existem duas maneiras -

  • Você pode usar o Writable classes, fornecidas pela biblioteca nativa do Hadoop.

  • Você também pode usar Sequence Files que armazenam os dados em formato binário.

A principal desvantagem desses dois mecanismos é que Writables e SequenceFiles possuem apenas uma API Java e não podem ser escritos ou lidos em qualquer outra linguagem.

Portanto, qualquer um dos arquivos criados no Hadoop com os dois mecanismos acima não podem ser lidos por qualquer outro terceiro idioma, o que torna o Hadoop uma caixa limitada. Para resolver esta desvantagem, Doug Cutting criouAvro, que é um language independent data structure.