AVRO - Guía rápida

Para transferir datos a través de una red o para su almacenamiento persistente, debe serializar los datos. Antes de laserialization APIs proporcionada por Java y Hadoop, tenemos una utilidad especial, llamada Avro, una técnica de serialización basada en esquemas.

Este tutorial le enseña cómo serializar y deserializar los datos usando Avro. Avro proporciona bibliotecas para varios lenguajes de programación. En este tutorial, demostramos los ejemplos usando la biblioteca de Java.

¿Qué es Avro?

Apache Avro es un sistema de serialización de datos independiente del lenguaje. Fue desarrollado por Doug Cutting, el padre de Hadoop. Dado que las clases de escritura de Hadoop carecen de portabilidad de idiomas, Avro se vuelve bastante útil, ya que trata con formatos de datos que pueden procesarse en varios idiomas. Avro es una herramienta preferida para serializar datos en Hadoop.

Avro tiene un sistema basado en esquemas. Un esquema independiente del lenguaje está asociado con sus operaciones de lectura y escritura. Avro serializa los datos que tienen un esquema integrado. Avro serializa los datos en un formato binario compacto, que puede ser deserializado por cualquier aplicación.

Avro usa el formato JSON para declarar las estructuras de datos. Actualmente, admite lenguajes como Java, C, C ++, C #, Python y Ruby.

Esquemas de Avro

Avro depende en gran medida de su schema. Permite que todos los datos se escriban sin conocimiento previo del esquema. Se serializa rápidamente y los datos serializados resultantes son de menor tamaño. El esquema se almacena junto con los datos de Avro en un archivo para su posterior procesamiento.

En RPC, el cliente y el servidor intercambian esquemas durante la conexión. Este intercambio ayuda en la comunicación entre campos con el mismo nombre, campos faltantes, campos adicionales, etc.

Los esquemas de Avro se definen con JSON que simplifica su implementación en lenguajes con librerías JSON.

Al igual que Avro, hay otros mecanismos de serialización en Hadoop como Sequence Files, Protocol Buffers, y Thrift.

Comparación con búferes de ahorro y protocolo

Thrift y Protocol Buffersson las bibliotecas más competentes con Avro. Avro se diferencia de estos marcos de las siguientes formas:

  • Avro admite tipos dinámicos y estáticos según el requisito. Protocol Buffers y Thrift utilizan lenguajes de definición de interfaz (IDL) para especificar esquemas y sus tipos. Estos IDL se utilizan para generar código para la serialización y deserialización.

  • Avro está construido en el ecosistema Hadoop. Los búferes de protocolo y de ahorro no están integrados en el ecosistema de Hadoop.

A diferencia de Thrift y Protocol Buffer, la definición de esquema de Avro está en JSON y no en ningún IDL propietario.

Propiedad Avro Búfer de ahorro y protocolo
Esquema dinámico si No
Integrado en Hadoop si No
Esquema en JSON si No
No es necesario compilar si No
No es necesario declarar identificaciones si No
Filo sangriento si No

Características de Avro

A continuación se enumeran algunas de las características destacadas de Avro:

  • Avro es un language-neutral sistema de serialización de datos.

  • Puede ser procesado por muchos lenguajes (actualmente C, C ++, C #, Java, Python y Ruby).

  • Avro crea un formato estructurado binario que es a la vez compressible y splittable. Por lo tanto, se puede usar de manera eficiente como entrada para trabajos de Hadoop MapReduce.

  • Avro proporciona rich data structures. Por ejemplo, puede crear un registro que contenga una matriz, un tipo enumerado y un subregistro. Estos tipos de datos se pueden crear en cualquier idioma, se pueden procesar en Hadoop y los resultados se pueden enviar a un tercer idioma.

  • Avro schemas definido en JSON, facilitar la implementación en los lenguajes que ya tienen bibliotecas JSON.

  • Avro crea un archivo de autodescripción llamado Avro Data File, en el que almacena datos junto con su esquema en la sección de metadatos.

  • Avro también se utiliza en llamadas a procedimiento remoto (RPC). Durante RPC, el cliente y el servidor intercambian esquemas en el protocolo de enlace de la conexión.

Trabajo general de Avro

Para usar Avro, debe seguir el flujo de trabajo dado:

  • Step 1- Crea esquemas. Aquí debe diseñar el esquema Avro de acuerdo con sus datos.

  • Step 2- Lea los esquemas en su programa. Se hace de dos formas:

    • By Generating a Class Corresponding to Schema- Compile el esquema usando Avro. Esto genera un archivo de clase correspondiente al esquema.

    • By Using Parsers Library - Puede leer directamente el esquema utilizando la biblioteca de analizadores.

  • Step 3 - Serialice los datos utilizando la API de serialización proporcionada para Avro, que se encuentra en el package org.apache.avro.specific.

  • Step 4 - Deserializar los datos utilizando la API de deserialización proporcionada para Avro, que se encuentra en la package org.apache.avro.specific.

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 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 deserializarlos nuevamente. 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 a 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 puede ser leído por 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.

La base del software Apache proporciona a Avro varias versiones. Puede descargar la versión requerida de los espejos de Apache. Veamos, cómo configurar el entorno para trabajar con Avro -

Descargando Avro

Para descargar Apache Avro, proceda con lo siguiente:

  • Abra la página web Apache.org . Verá la página de inicio de Apache Avro como se muestra a continuación:

  • Haga clic en proyecto → lanzamientos. Obtendrá una lista de lanzamientos.

  • Seleccione la última versión que lo lleva a un enlace de descarga.

  • mirror.nexcess es uno de los enlaces donde puede encontrar la lista de todas las bibliotecas de diferentes idiomas que admite Avro, como se muestra a continuación:

Puede seleccionar y descargar la biblioteca para cualquiera de los idiomas proporcionados. En este tutorial usamos Java. Por lo tanto, descargue los archivos jaravro-1.7.7.jar y avro-tools-1.7.7.jar.

Avro con Eclipse

Para utilizar Avro en el entorno Eclipse, debe seguir los pasos que se indican a continuación:

  • Step 1. Eclipse abierto.

  • Step 2. Crea un proyecto.

  • Step 3.Haz clic derecho en el nombre del proyecto. Obtendrá un menú de acceso directo.

  • Step 4. Haga clic en Build Path. Le lleva a otro menú de acceso directo.

  • Step 5. Haga clic en Configure Build Path... Puede ver la ventana Propiedades de su proyecto como se muestra a continuación:

  • Step 6. En la pestaña de bibliotecas, haga clic en ADD EXternal JARs... botón.

  • Step 7. Seleccione el archivo jar avro-1.77.jar que ha descargado.

  • Step 8. Haga clic en OK.

Avro con Maven

También puede obtener la biblioteca Avro en su proyecto usando Maven. A continuación se muestra el archivo pom.xml para 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>

Configuración de Classpath

Para trabajar con Avro en el entorno Linux, descargue los siguientes archivos jar:

  • avro-1.77.jar
  • avro-tools-1.77.jar
  • log4j-api-2.0-beta9.jar
  • og4j-core-2.0.beta9.jar.

Copie estos archivos en una carpeta y establezca la ruta de clase a la carpeta, en formato./bashrc archivo como se muestra a continuación.

#class path for Avro
export CLASSPATH=$CLASSPATH://home/Hadoop/Avro_Work/jars/*

Avro, al ser una utilidad de serialización basada en esquemas, acepta esquemas como entrada. A pesar de que hay varios esquemas disponibles, Avro sigue sus propios estándares para definir esquemas. Estos esquemas describen los siguientes detalles:

  • tipo de archivo (registro por defecto)
  • ubicación del registro
  • nombre del registro
  • campos en el registro con sus tipos de datos correspondientes

Con estos esquemas, puede almacenar valores serializados en formato binario con menos espacio. Estos valores se almacenan sin metadatos.

Crear esquemas de Avro

El esquema Avro se crea en formato de documento JavaScript Object Notation (JSON), que es un formato ligero de intercambio de datos basado en texto. Se crea de una de las siguientes formas:

  • Una cadena JSON
  • Un objeto JSON
  • Una matriz JSON

Example - El siguiente ejemplo muestra un esquema, que define un documento, bajo el espacio de nombres Tutorialspoint, con nombre Empleado, que tiene campos nombre y edad.

{
   "type" : "record",
   "namespace" : "Tutorialspoint",
   "name" : "Employee",
   "fields" : [
      { "name" : "Name" , "type" : "string" },
      { "name" : "Age" , "type" : "int" }
   ]
}

En este ejemplo, puede observar que hay cuatro campos para cada registro:

  • type - Este campo se encuentra debajo del documento, así como debajo del campo llamado campos.

    • En caso de documento, muestra el tipo de documento, generalmente un registro porque hay varios campos.

    • Cuando es un campo, el tipo describe el tipo de datos.

  • namespace - Este campo describe el nombre del espacio de nombres en el que reside el objeto.

  • name - Este campo se encuentra debajo del documento, así como debajo del campo llamado campos.

    • En caso de documento, describe el nombre del esquema. Este nombre de esquema, junto con el espacio de nombres, identifica de forma única el esquema dentro de la tienda (Namespace.schema name). En el ejemplo anterior, el nombre completo del esquema será Tutorialspoint.Employee.

    • En el caso de los campos, describe el nombre del campo.

Tipos de datos primitivos de Avro

El esquema Avro tiene tipos de datos primitivos y tipos de datos complejos. La siguiente tabla describe elprimitive data types de Avro -

Tipo de datos Descripción
nulo Null es un tipo que no tiene valor.
En t Entero de 32 bits con signo.
largo Entero de 64 bits con signo.
flotador número de punto flotante IEEE 754 de precisión simple (32 bits).
doble número de coma flotante IEEE 754 de doble precisión (64 bits).
bytes secuencia de bytes sin firmar de 8 bits.
cuerda Secuencia de caracteres Unicode.

Tipos de datos complejos de Avro

Junto con los tipos de datos primitivos, Avro proporciona seis tipos de datos complejos, a saber, registros, enumeraciones, matrices, mapas, uniones y fijos.

Grabar

Un tipo de datos de registro en Avro es una colección de múltiples atributos. Admite los siguientes atributos:

  • name - El valor de este campo contiene el nombre del registro.

  • namespace - El valor de este campo contiene el nombre del espacio de nombres donde se almacena el objeto.

  • type - El valor de este atributo contiene el tipo de documento (registro) o el tipo de datos del campo en el esquema.

  • fields - Este campo contiene una matriz JSON, que tiene la lista de todos los campos del esquema, cada uno con el nombre y los atributos de tipo.

Example

A continuación se muestra el ejemplo de un registro.

{
" type " : "record",
" namespace " : "Tutorialspoint",
" name " : "Employee",
" fields " : [
 { "name" : " Name" , "type" : "string" },
 { "name" : "age" , "type" : "int" }
 ]
}

Enum

Una enumeración es una lista de elementos en una colección, la enumeración Avro admite los siguientes atributos:

  • name - El valor de este campo contiene el nombre de la enumeración.

  • namespace - El valor de este campo contiene la cadena que califica el nombre de la Enumeración.

  • symbols - El valor de este campo contiene los símbolos de la enumeración como una matriz de nombres.

Example

A continuación se muestra el ejemplo de una enumeración.

{
   "type" : "enum",
   "name" : "Numbers", 
   "namespace": "data", 
   "symbols" : [ "ONE", "TWO", "THREE", "FOUR" ]
}

Matrices

Este tipo de datos define un campo de matriz que tiene elementos de un solo atributo. Este atributo de elementos especifica el tipo de elementos de la matriz.

Example

{ " type " : " array ", " items " : " int " }

Mapas

El tipo de datos del mapa es una matriz de pares clave-valor, organiza los datos como pares clave-valor. La clave de un mapa de Avro debe ser una cadena. Los valores de un mapa contienen el tipo de datos del contenido del mapa.

Example

{"type" : "map", "values" : "int"}

Sindicatos

Se utiliza un tipo de datos de unión siempre que el campo tiene uno o más tipos de datos. Se representan como matrices JSON. Por ejemplo, si un campo puede ser int o nulo, entonces la unión se representa como ["int", "nulo"].

Example

A continuación se muestra un documento de ejemplo que utiliza uniones:

{ 
   "type" : "record", 
   "namespace" : "tutorialspoint", 
   "name" : "empdetails ", 
   "fields" : 
   [ 
      { "name" : "experience", "type": ["int", "null"] }, { "name" : "age", "type": "int" } 
   ] 
}

Fijo

Este tipo de datos se utiliza para declarar un campo de tamaño fijo que se puede utilizar para almacenar datos binarios. Tiene nombre de campo y datos como atributos. El nombre contiene el nombre del campo y el tamaño tiene el tamaño del campo.

Example

{ "type" : "fixed" , "name" : "bdata", "size" : 1048576}

En el capítulo anterior, describimos el tipo de entrada de Avro, es decir, esquemas de Avro. En este capítulo, explicaremos las clases y métodos utilizados en la serialización y deserialización de esquemas Avro.

Clase SpecificDatumWriter

Esta clase pertenece al paquete org.apache.avro.specific. Implementa laDatumWriter interfaz que convierte objetos Java en un formato serializado en memoria.

Constructor

S.No. Descripción
1 SpecificDatumWriter(Schema schema)

Método

S.No. Descripción
1

SpecificData getSpecificData()

Devuelve la implementación de SpecificData utilizada por este escritor.

Clase SpecificDatumReader

Esta clase pertenece al paquete org.apache.avro.specific. Implementa laDatumReader interfaz que lee los datos de un esquema y determina la representación de datos en memoria. SpecificDatumReader es la clase que admite clases java generadas.

Constructor

S.No. Descripción
1

SpecificDatumReader(Schema schema)

Construya dónde los esquemas del escritor y del lector son iguales.

Métodos

S.No. Descripción
1

SpecificData getSpecificData()

Devuelve los datos específicos contenidos.

2

void setSchema(Schema actual)

Este método se utiliza para establecer el esquema del escritor.

DataFileWriter

Instancia DataFileWrite para empclase. Esta clase escribe una secuencia de registros serializados de datos que se ajustan a un esquema, junto con el esquema en un archivo.

Constructor

S.No. Descripción
1 DataFileWriter(DatumWriter<D> dout)

Métodos

S. No Descripción
1

void append(D datum)

Agrega un dato a un archivo.

2

DataFileWriter<D> appendTo(File file)

Este método se utiliza para abrir un escritor que se agrega a un archivo existente.

Lector de archivos de datos

Esta clase proporciona acceso aleatorio a archivos escritos con DataFileWriter. Hereda la claseDataFileStream.

Constructor

S.No. Descripción
1 DataFileReader(File file, DatumReader<D> reader))

Métodos

S.No. Descripción
1

next()

Lee el siguiente dato del archivo.

2

Boolean hasNext()

Devuelve verdadero si quedan más entradas en este archivo.

Clase Schema.parser

Esta clase es un analizador de esquemas en formato JSON. Contiene métodos para analizar el esquema. Pertenece aorg.apache.avro paquete.

Constructor

S.No. Descripción
1 Schema.Parser()

Métodos

S.No. Descripción
1

parse (File file)

Analiza el esquema proporcionado en el file.

2

parse (InputStream in)

Analiza el esquema proporcionado en el InputStream.

3

parse (String s)

Analiza el esquema proporcionado en el String.

Interfaz GenricRecord

Esta interfaz proporciona métodos para acceder a los campos por nombre e índice.

Métodos

S.No. Descripción
1

Object get(String key)

Devuelve el valor de un campo dado.

2

void put(String key, Object v)

Establece el valor de un campo dado su nombre.

Clase GenericData.Record

Constructor

S.No. Descripción
1 GenericData.Record(Schema schema)

Métodos

S.No. Descripción
1

Object get(String key)

Devuelve el valor de un campo del nombre de pila.

2

Schema getSchema()

Devuelve el esquema de esta instancia.

3

void put(int i, Object v)

Establece el valor de un campo dada su posición en el esquema.

4

void put(String key, Object value)

Establece el valor de un campo dado su nombre.

Uno puede leer un esquema de Avro en el programa generando una clase correspondiente a un esquema o usando la biblioteca de analizadores. Este capítulo describe cómo leer el esquemaby generating a class y Serializing los datos usando Avr.

Serialización generando una clase

Para serializar los datos con Avro, siga los pasos que se indican a continuación:

  • Escribe un esquema de Avro.

  • Compile el esquema con la utilidad Avro. Obtienes el código Java correspondiente a ese esquema.

  • Complete el esquema con los datos.

  • Serialícelo usando la biblioteca Avro.

Definición de un esquema

Suponga que desea un esquema con los siguientes detalles:

Field Nombre carné de identidad años salario habla a
type Cuerda En t En t En t cuerda

Cree un esquema de Avro como se muestra a continuación.

Guardarlo como 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"}
   ]
}

Compilar el esquema

Después de crear un esquema de Avro, debe compilar el esquema creado con las herramientas de Avro. avro-tools-1.7.7.jar es el frasco que contiene las herramientas.

Sintaxis para compilar un esquema Avro

java -jar <path/to/avro-tools-1.7.7.jar> compile schema <path/to/schema-file> <destination-folder>

Abra el terminal en la carpeta de inicio.

Cree un nuevo directorio para trabajar con Avro como se muestra a continuación:

$ mkdir Avro_Work

En el directorio recién creado, cree tres subdirectorios:

  • Primer nombre schema, para colocar el esquema.

  • Segundo nombrado with_code_gen, para colocar el código generado.

  • Tercer nombrado jars, para colocar los archivos jar.

$ mkdir schema
$ mkdir with_code_gen
$ mkdir jars

La siguiente captura de pantalla muestra cómo Avro_work La carpeta debería verse como después de crear todos los directorios.

  • Ahora /home/Hadoop/Avro_work/jars/avro-tools-1.7.7.jar es la ruta del directorio donde descargó el archivo avro-tools-1.7.7.jar.

  • /home/Hadoop/Avro_work/schema/ es la ruta del directorio donde se almacena el archivo de esquema emp.avsc.

  • /home/Hadoop/Avro_work/with_code_gen es el directorio donde desea que se almacenen los archivos de clase generados.

Ahora compile el esquema como se muestra a continuación:

$ 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

Después de la compilación, se crea un paquete de acuerdo con el espacio de nombres del esquema en el directorio de destino. Dentro de este paquete, se crea el código fuente de Java con el nombre del esquema. Este código fuente generado es el código Java del esquema dado que se puede utilizar directamente en las aplicaciones.

Por ejemplo, en este caso un paquete / carpeta, llamado tutorialspoint se crea la cual contiene otra carpeta llamada com (ya que el espacio de nombre es tutorialspoint.com) y dentro de ella se puede observar el archivo generado emp.java. La siguiente instantánea muestraemp.java -

Esta clase es útil para crear datos según el esquema.

La clase generada contiene:

  • Constructor por defecto y constructor parametrizado que acepta todas las variables del esquema.
  • Los métodos setter y getter para todas las variables del esquema.
  • Método Get () que devuelve el esquema.
  • Métodos constructores.

Crear y serializar los datos

En primer lugar, copie el archivo java generado utilizado en este proyecto en el directorio actual o impórtelo desde donde se encuentra.

Ahora podemos escribir un nuevo archivo Java y crear una instancia de la clase en el archivo generado (emp) para agregar datos de empleados al esquema.

Veamos el procedimiento para crear datos según el esquema usando Apache Avro.

Paso 1

Instancia de lo generado emp clase.

emp e1=new emp( );

Paso 2

Utilizando métodos de establecimiento, inserte los datos del primer empleado. Por ejemplo, hemos creado los detalles del empleado llamado Omar.

e1.setName("omar");
e1.setAge(21);
e1.setSalary(30000);
e1.setAddress("Hyderabad");
e1.setId(001);

De manera similar, complete todos los detalles de los empleados utilizando métodos de establecimiento.

Paso 3

Crea un objeto de DatumWriter interfaz usando el SpecificDatumWriterclase. Esto convierte los objetos Java en un formato serializado en memoria. El siguiente ejemplo crea una instanciaSpecificDatumWriter objeto de clase para emp clase.

DatumWriter<emp> empDatumWriter = new SpecificDatumWriter<emp>(emp.class);

Etapa 4

Instanciar DataFileWriter para empclase. Esta clase escribe una secuencia de registros serializados de datos que se ajustan a un esquema, junto con el esquema en sí, en un archivo. Esta clase requiereDatumWriter objeto, como un parámetro para el constructor.

DataFileWriter<emp> empFileWriter = new DataFileWriter<emp>(empDatumWriter);

Paso 5

Abra un nuevo archivo para almacenar los datos que coinciden con el esquema dado usando create()método. Este método requiere el esquema y la ruta del archivo donde se almacenarán los datos como parámetros.

En el siguiente ejemplo, el esquema se pasa usando getSchema() método, y el archivo de datos se almacena en la ruta - /home/Hadoop/Avro/serialized_file/emp.avro.

empFileWriter.create(e1.getSchema(),new File("/home/Hadoop/Avro/serialized_file/emp.avro"));

Paso 6

Agregue todos los registros creados al archivo usando append() método como se muestra a continuación -

empFileWriter.append(e1);
empFileWriter.append(e2);
empFileWriter.append(e3);

Ejemplo: serialización generando una clase

El siguiente programa completo muestra cómo serializar datos en un archivo usando 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");
   }
}

Navegue por el directorio donde se coloca el código generado. En este caso, enhome/Hadoop/Avro_work/with_code_gen.

In Terminal −

$ cd home/Hadoop/Avro_work/with_code_gen/

In GUI −

Ahora copie y guarde el programa anterior en el archivo llamado Serialize.java

Compílelo y ejecútelo como se muestra a continuación:

$ javac Serialize.java
$ java Serialize

Salida

data successfully serialized

Si verifica la ruta proporcionada en el programa, puede encontrar el archivo serializado generado como se muestra a continuación.

Como se describió anteriormente, se puede leer un esquema de Avro en un programa generando una clase correspondiente al esquema o usando la biblioteca de analizadores. Este capítulo describe cómo leer el esquemaby generating a class y Deserialize los datos usando Avro.

Deserialización generando una clase

Los datos serializados se almacenan en el archivo emp.avro. Puede deserializarlo y leerlo con Avro.

Siga el procedimiento que se indica a continuación para deserializar los datos serializados de un archivo.

Paso 1

Crea un objeto de DatumReader interfaz usando SpecificDatumReader clase.

DatumReader<emp>empDatumReader = new SpecificDatumReader<emp>(emp.class);

Paso 2

Instanciar DataFileReader para empclase. Esta clase lee datos serializados de un archivo. Requiere elDataumeader objeto y ruta del archivo donde existen los datos serializados, como parámetros para el constructor.

DataFileReader<emp> dataFileReader = new DataFileReader(new File("/path/to/emp.avro"), empDatumReader);

Paso 3

Imprima los datos deserializados, utilizando los métodos de DataFileReader.

  • los hasNext() El método devolverá un booleano si hay algún elemento en el Reader.

  • los next() método de DataFileReader devuelve los datos en el lector.

while(dataFileReader.hasNext()){

   em=dataFileReader.next(em);
   System.out.println(em);
}

Ejemplo: deserialización generando una clase

El siguiente programa completo muestra cómo deserializar los datos en un archivo usando 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);
      }
   }
}

Busque en el directorio donde se coloca el código generado. En este caso, enhome/Hadoop/Avro_work/with_code_gen.

$ cd home/Hadoop/Avro_work/with_code_gen/

Ahora, copie y guarde el programa anterior en el archivo llamado DeSerialize.java. Compílelo y ejecútelo como se muestra a continuación:

$ javac Deserialize.java
$ java Deserialize

Salida

{"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"}

Se puede leer un esquema Avro en un programa generando una clase correspondiente a un esquema o utilizando la biblioteca de analizadores. En Avro, los datos siempre se almacenan con su esquema correspondiente. Por lo tanto, siempre podemos leer un esquema sin generar código.

Este capítulo describe cómo leer el esquema by using parsers library y para serialize los datos usando Avro.

Serialización mediante la biblioteca de analizadores

Para serializar los datos, necesitamos leer el esquema, crear datos de acuerdo con el esquema y serializar el esquema usando la API de Avro. El siguiente procedimiento serializa los datos sin generar ningún código:

Paso 1

En primer lugar, lea el esquema del archivo. Para hacerlo, useSchema.Parserclase. Esta clase proporciona métodos para analizar el esquema en diferentes formatos.

Instancia del Schema.Parser class pasando la ruta del archivo donde se almacena el esquema.

Schema schema = new Schema.Parser().parse(new File("/path/to/emp.avsc"));

Paso 2

Crea el objeto de GenericRecord interfaz, instanciando GenericData.Recordclase como se muestra a continuación. Pase el objeto de esquema creado anteriormente a su constructor.

GenericRecord e1 = new GenericData.Record(schema);

Paso 3

Inserte los valores en el esquema usando el put() método del GenericData clase.

e1.put("name", "ramu");
e1.put("id", 001);
e1.put("salary",30000);
e1.put("age", 25);
e1.put("address", "chennai");

Etapa 4

Crea un objeto de DatumWriter interfaz usando el SpecificDatumWriterclase. Convierte objetos Java en formato serializado en memoria. El siguiente ejemplo crea una instanciaSpecificDatumWriter objeto de clase para emp clase -

DatumWriter<emp> empDatumWriter = new SpecificDatumWriter<emp>(emp.class);

Paso 5

Instanciar DataFileWriter para empclase. Esta clase escribe registros serializados de datos que se ajustan a un esquema, junto con el propio esquema, en un archivo. Esta clase requiere elDatumWriter objeto, como un parámetro para el constructor.

DataFileWriter<emp> dataFileWriter = new DataFileWriter<emp>(empDatumWriter);

Paso 6

Abra un nuevo archivo para almacenar los datos que coinciden con el esquema dado usando create()método. Este método requiere el esquema y la ruta del archivo donde se almacenarán los datos como parámetros.

En el ejemplo que se muestra a continuación, el esquema se pasa usando getSchema() método y el archivo de datos se almacena en la ruta

/home/Hadoop/Avro/serialized_file/emp.avro.

empFileWriter.create(e1.getSchema(), new
File("/home/Hadoop/Avro/serialized_file/emp.avro"));

Paso 7

Agregue todos los registros creados al archivo usando append( ) método como se muestra a continuación.

empFileWriter.append(e1);
empFileWriter.append(e2);
empFileWriter.append(e3);

Ejemplo: serialización mediante analizadores

El siguiente programa completo muestra cómo serializar los datos usando analizadores:

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”);
   }
}

Busque en el directorio donde se coloca el código generado. En este caso, enhome/Hadoop/Avro_work/without_code_gen.

$ cd home/Hadoop/Avro_work/without_code_gen/

Ahora copie y guarde el programa anterior en el archivo llamado Serialize.java. Compílelo y ejecútelo como se muestra a continuación:

$ javac Serialize.java
$ java Serialize

Salida

data successfully serialized

Si verifica la ruta proporcionada en el programa, puede encontrar el archivo serializado generado como se muestra a continuación.

Como se mencionó anteriormente, se puede leer un esquema de Avro en un programa generando una clase correspondiente a un esquema o usando la biblioteca de analizadores. En Avro, los datos siempre se almacenan con su esquema correspondiente. Por lo tanto, siempre podemos leer un artículo serializado sin generación de código.

Este capítulo describe cómo leer el esquema using parsers library y Deserializing los datos usando Avro.

Deserialización mediante la biblioteca de analizadores

Los datos serializados se almacenan en el archivo mydata.txt. Puede deserializarlo y leerlo con Avro.

Siga el procedimiento que se indica a continuación para deserializar los datos serializados de un archivo.

Paso 1

En primer lugar, lea el esquema del archivo. Para hacerlo, useSchema.Parserclase. Esta clase proporciona métodos para analizar el esquema en diferentes formatos.

Instancia del Schema.Parser class pasando la ruta del archivo donde se almacena el esquema.

Schema schema = new Schema.Parser().parse(new File("/path/to/emp.avsc"));

Paso 2

Crea un objeto de DatumReader interfaz usando SpecificDatumReader clase.

DatumReader<emp>empDatumReader = new SpecificDatumReader<emp>(emp.class);

Paso 3

Instanciar DataFileReaderclase. Esta clase lee datos serializados de un archivo. Requiere elDatumReader objeto y ruta del archivo donde existen los datos serializados, como parámetros para el constructor.

DataFileReader<GenericRecord> dataFileReader = new DataFileReader<GenericRecord>(new File("/path/to/mydata.txt"), datumReader);

Etapa 4

Imprima los datos deserializados, utilizando los métodos de DataFileReader.

  • los hasNext() El método devuelve un booleano si hay elementos en el Reader.

  • los next() método de DataFileReader devuelve los datos en el lector.

while(dataFileReader.hasNext()){

   em=dataFileReader.next(em);
   System.out.println(em);
}

Ejemplo: deserialización mediante la biblioteca de analizadores

El siguiente programa completo muestra cómo deserializar los datos serializados usando la biblioteca 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");
   }
}

Busque en el directorio donde se coloca el código generado. En este caso, está enhome/Hadoop/Avro_work/without_code_gen.

$ cd home/Hadoop/Avro_work/without_code_gen/

Ahora copie y guarde el programa anterior en el archivo llamado DeSerialize.java. Compílelo y ejecútelo como se muestra a continuación:

$ javac Deserialize.java
$ java Deserialize

Salida

{"name": "ramu", "id": 1, "salary": 30000, "age": 25, "address": "chennai"}
{"name": "rahman", "id": 2, "salary": 35000, "age": 30, "address": "Delhi"}