AVRO - Szybki przewodnik

Aby przesłać dane przez sieć lub w celu ich trwałego przechowywania, należy zserializować dane. Przedserialization APIs udostępniane przez Java i Hadoop, mamy specjalne narzędzie o nazwie Avro, technika serializacji oparta na schemacie.

W tym samouczku przedstawiono sposób serializacji i deserializacji danych przy użyciu programu Avro. Avro zapewnia biblioteki dla różnych języków programowania. W tym samouczku przedstawiamy przykłady przy użyciu biblioteki Java.

Co to jest Avro?

Apache Avro to niezależny od języka system serializacji danych. Został opracowany przez Douga Cuttinga, ojca Hadoopa. Ponieważ klasom Hadoop zapisywalnym brakuje przenośności języków, Avro staje się bardzo pomocny, ponieważ radzi sobie z formatami danych, które mogą być przetwarzane w wielu językach. Avro jest preferowanym narzędziem do serializacji danych w Hadoop.

Avro ma system oparty na schemacie. Schemat niezależny od języka jest powiązany z operacjami odczytu i zapisu. Avro serializuje dane, które mają wbudowany schemat. Avro serializuje dane do kompaktowego formatu binarnego, który może być deserializowany przez dowolną aplikację.

Avro używa formatu JSON do deklarowania struktur danych. Obecnie obsługuje języki takie jak Java, C, C ++, C #, Python i Ruby.

Schematy Avro

Avro w dużym stopniu zależy od tego schema. Pozwala na zapis wszystkich danych bez wcześniejszej znajomości schematu. Szybko serializuje, a wynikowe zserializowane dane mają mniejszy rozmiar. Schemat jest przechowywany wraz z danymi Avro w pliku do dalszego przetwarzania.

W RPC klient i serwer wymieniają schematy podczas połączenia. Ta wymiana pomaga w komunikacji między tymi samymi nazwanymi polami, brakującymi polami, dodatkowymi polami itp.

Schematy Avro są definiowane za pomocą JSON, co upraszcza ich implementację w językach z bibliotekami JSON.

Podobnie jak Avro, istnieją inne mechanizmy serializacji w Hadoop, takie jak Sequence Files, Protocol Buffers, i Thrift.

Porównanie z buforami oszczędności i protokołów

Thrift i Protocol Buffersto najbardziej kompetentne biblioteki z Avro. Avro różni się od tych frameworków w następujący sposób -

  • Avro obsługuje zarówno typy dynamiczne, jak i statyczne, zgodnie z wymaganiami. Bufory protokołów i oszczędność używają języków definicji interfejsu (IDL) do określania schematów i ich typów. Te IDL są używane do generowania kodu do serializacji i deserializacji.

  • Avro jest zbudowany w ekosystemie Hadoop. Bufory oszczędności i protokołów nie są wbudowane w ekosystem Hadoop.

W przeciwieństwie do Thrift i Protocol Buffer, definicja schematu Avro jest w JSON, a nie w żadnym zastrzeżonym IDL.

własność Avro Bufor oszczędzania i protokołu
Schemat dynamiczny tak Nie
Wbudowany w Hadoop tak Nie
Schemat w JSON tak Nie
Nie ma potrzeby kompilacji tak Nie
Nie ma potrzeby deklarowania identyfikatorów tak Nie
Krwawiąca krawędź tak Nie

Funkcje Avro

Poniżej wymienione są niektóre z najważniejszych cech Avro -

  • Avro jest language-neutral system serializacji danych.

  • Może być przetwarzany w wielu językach (obecnie C, C ++, C #, Java, Python i Ruby).

  • Avro tworzy binarny format strukturalny, który jest jednym i drugim compressible i splittable. W związku z tym może być efektywnie używany jako dane wejściowe do zadań Hadoop MapReduce.

  • Avro zapewnia rich data structures. Na przykład możesz utworzyć rekord zawierający tablicę, typ wyliczeniowy i rekord podrzędny. Te typy danych można tworzyć w dowolnym języku, przetwarzać w Hadoop, a wyniki mogą być przesyłane do trzeciego języka.

  • Avro schemas zdefiniowane w JSON, ułatwiają implementację w językach, które mają już biblioteki JSON.

  • Avro tworzy samoopisujący się plik o nazwie Avro Data File, w którym przechowuje dane wraz ze schematem w sekcji metadanych.

  • Avro jest również używany w zdalnych wywołaniach procedur (RPC). Podczas RPC klient i serwer wymieniają schematy podczas uzgadniania połączenia.

Ogólne działanie Avro

Aby korzystać z Avro, musisz postępować zgodnie z podanym przepływem pracy -

  • Step 1- Twórz schematy. Tutaj musisz zaprojektować schemat Avro zgodnie z Twoimi danymi.

  • Step 2- Wczytaj schematy do swojego programu. Odbywa się to na dwa sposoby -

    • By Generating a Class Corresponding to Schema- Skompiluj schemat za pomocą Avro. Spowoduje to wygenerowanie pliku klasy odpowiadającego schematowi

    • By Using Parsers Library - Możesz bezpośrednio odczytać schemat za pomocą biblioteki parserów.

  • Step 3 - Serializuj dane za pomocą interfejsu API serializacji dostarczonego dla Avro, który znajduje się w package org.apache.avro.specific.

  • Step 4 - Deserializacja danych przy użyciu interfejsu API deserializacji dostarczonego dla Avro, który znajduje się w package org.apache.avro.specific.

Dane są serializowane dla dwóch celów -

  • Do trwałego przechowywania

  • Do przesyłania danych przez sieć

Co to jest serializacja?

Serializacja to proces tłumaczenia struktur danych lub stanu obiektów na postać binarną lub tekstową w celu transportu danych przez sieć lub przechowywania w trwałej pamięci. Po przesłaniu danych przez sieć lub pobraniu z pamięci trwałej należy ponownie przeprowadzić deserializację. Serializacja jest określana jakomarshalling a deserializacja jest określana jako unmarshalling.

Serializacja w Javie

Java udostępnia mechanizm o nazwie object serialization gdzie obiekt może być reprezentowany jako sekwencja bajtów, która zawiera dane obiektu, a także informacje o typie obiektu i typach danych przechowywanych w obiekcie.

Po zapisaniu zserializowanego obiektu do pliku można go odczytać z pliku i zdeserializować. Oznacza to, że informacje o typie i bajty, które reprezentują obiekt i jego dane, mogą zostać użyte do ponownego utworzenia obiektu w pamięci.

ObjectInputStream i ObjectOutputStream Klasy są używane do serializacji i deserializacji obiektu odpowiednio w Javie.

Serializacja w Hadoop

Ogólnie w systemach rozproszonych, takich jak Hadoop, koncepcja serializacji jest używana do Interprocess Communication i Persistent Storage.

Komunikacja międzyprocesowa

  • Do nawiązania komunikacji międzyprocesowej pomiędzy węzłami połączonymi w sieci wykorzystano technikę RPC.

  • RPC wykorzystało wewnętrzną serializację do konwersji wiadomości na format binarny przed wysłaniem jej do zdalnego węzła przez sieć. Z drugiej strony system zdalny deserializuje strumień binarny do oryginalnej wiadomości.

  • Format serializacji RPC musi być następujący:

    • Compact - Aby jak najlepiej wykorzystać przepustowość sieci, która jest najbardziej rzadkim zasobem w centrum danych.

    • Fast - Ponieważ komunikacja między węzłami ma kluczowe znaczenie w systemach rozproszonych, proces serializacji i deserializacji powinien być szybki i generować mniej narzutów.

    • Extensible - Protokoły zmieniają się w czasie, aby sprostać nowym wymaganiom, dlatego też rozwijanie protokołu w sposób kontrolowany dla klientów i serwerów powinno być proste.

    • Interoperable - Format wiadomości powinien obsługiwać węzły napisane w różnych językach.

Pamięć trwała

Trwała pamięć masowa to cyfrowa pamięć masowa, która nie traci swoich danych w przypadku utraty zasilania. Pliki, foldery, bazy danych to przykłady trwałego przechowywania.

Zapisywalny interfejs

To jest interfejs w Hadoop, który udostępnia metody serializacji i deserializacji. W poniższej tabeli opisano metody -

S.No. Metody i opis
1

void readFields(DataInput in)

Ta metoda służy do deserializacji pól danego obiektu.

2

void write(DataOutput out)

Ta metoda służy do serializacji pól danego obiektu.

Zapisywalny porównywalny interfejs

To jest połączenie Writable i Comparableinterfejsy. Ten interfejs dziedziczyWritable interfejs Hadoop, a także Comparableinterfejs Java. W związku z tym zapewnia metody serializacji danych, deserializacji i porównania.

S.No. Metody i opis
1

int compareTo(class obj)

Ta metoda porównuje bieżący obiekt z danym obiektem obj.

Oprócz tych klas Hadoop obsługuje wiele klas otoki, które implementują interfejs WritableComparable. Każda klasa opakowuje typ podstawowy języka Java. Hierarchia klas serializacji Hadoop jest podana poniżej -

Te klasy są przydatne do serializacji różnych typów danych na platformie Hadoop. Na przykład rozważmyIntWritableklasa. Zobaczmy, jak ta klasa jest używana do serializacji i deserializacji danych na platformie Hadoop.

Klasa IntWritable

Ta klasa implementuje Writable, Comparable, i WritableComparableinterfejsy. Otacza w nim typ danych typu integer. Ta klasa udostępnia metody używane do serializacji i deserializacji danych typu integer.

Konstruktorzy

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

Metody

S.No. Podsumowanie
1

int get()

Używając tej metody, możesz uzyskać liczbę całkowitą obecną w bieżącym obiekcie.

2

void readFields(DataInput in)

Ta metoda służy do deserializacji danych w podanym DataInput obiekt.

3

void set(int value)

Ta metoda służy do ustawiania wartości prądu IntWritable obiekt.

4

void write(DataOutput out)

Ta metoda służy do serializacji danych z bieżącego obiektu do podanego DataOutput obiekt.

Serializacja danych w Hadoop

Procedura serializacji danych typu całkowitego jest omówiona poniżej.

  • Utwórz instancję IntWritable klasy poprzez zawijanie w niej wartości całkowitej.

  • Utwórz instancję ByteArrayOutputStream klasa.

  • Utwórz instancję DataOutputStream klasę i przekaż obiekt ByteArrayOutputStream klasa do tego.

  • Serializuj wartość całkowitą w obiekcie IntWritable przy użyciu write()metoda. Ta metoda wymaga obiektu klasy DataOutputStream.

  • Zserializowane dane będą przechowywane w obiekcie tablicy bajtów, który jest przekazywany jako parametr do DataOutputStreamklasa w czasie tworzenia instancji. Konwertuj dane w obiekcie na tablicę bajtów.

Przykład

Poniższy przykład pokazuje, jak serializować dane typu całkowitego na platformie 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();
   }
}

Deserializacja danych na platformie Hadoop

Procedura deserializacji danych typu całkowitego jest omówiona poniżej -

  • Utwórz instancję IntWritable klasy poprzez zawijanie w niej wartości całkowitej.

  • Utwórz instancję ByteArrayOutputStream klasa.

  • Utwórz instancję DataOutputStream klasę i przekaż obiekt ByteArrayOutputStream klasa do tego.

  • Deserializacja danych w obiekcie DataInputStream za pomocą readFields() metoda klasy IntWritable.

  • Zdeserializowane dane będą przechowywane w obiekcie klasy IntWritable. Możesz odzyskać te dane za pomocąget() metoda tej klasy.

Przykład

Poniższy przykład pokazuje, jak deserializować dane typu całkowitego na platformie 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());
   }
}

Przewaga Hadoop nad serializacją Java

Oparta na zapisie serializacja Hadoop jest w stanie zmniejszyć obciążenie związane z tworzeniem obiektów przez ponowne użycie obiektów zapisywalnych, co nie jest możliwe w natywnej strukturze serializacji Java.

Wady serializacji Hadoop

Aby serializować dane Hadoop, istnieją dwa sposoby -

  • Możesz użyć Writable klasy, dostarczane przez natywną bibliotekę Hadoop.

  • Możesz także użyć Sequence Files które przechowują dane w formacie binarnym.

Główną wadą tych dwóch mechanizmów jest to Writables i SequenceFiles mają tylko Java API i nie można ich pisać ani czytać w żadnym innym języku.

Dlatego żaden z plików utworzonych w Hadoop z powyższymi dwoma mechanizmami nie może być odczytany przez żaden inny trzeci język, co sprawia, że ​​Hadoop jest ograniczonym pudełkiem. Aby rozwiązać ten problem, stworzył Doug CuttingAvro, który jest language independent data structure.

Fundacja oprogramowania Apache zapewnia Avro różne wersje. Możesz pobrać wymagane wydanie z serwerów lustrzanych Apache. Zobaczmy, jak skonfigurować środowisko do pracy z Avro -

Pobieranie Avro

Aby pobrać Apache Avro, wykonaj następujące czynności -

  • Otwórz stronę internetową Apache.org . Zobaczysz stronę główną Apache Avro, jak pokazano poniżej -

  • Kliknij projekt → wydania. Otrzymasz listę wydań.

  • Wybierz najnowszą wersję, która prowadzi do łącza pobierania.

  • mirror.nexcess jest jednym z linków, w którym można znaleźć listę wszystkich bibliotek różnych języków obsługiwanych przez Avro, jak pokazano poniżej -

Możesz wybrać i pobrać bibliotekę dla dowolnego z dostępnych języków. W tym samouczku używamy języka Java. Dlatego pobierz pliki jaravro-1.7.7.jar i avro-tools-1.7.7.jar.

Avro z Eclipse

Aby korzystać z Avro w środowisku Eclipse, należy wykonać poniższe czynności -

  • Step 1. Otwarte zaćmienie.

  • Step 2. Utwórz projekt.

  • Step 3.Kliknij prawym przyciskiem myszy nazwę projektu. Otrzymasz menu skrótów.

  • Step 4. Kliknij Build Path. Prowadzi do innego menu skrótów.

  • Step 5. Kliknij Configure Build Path... Możesz zobaczyć okno Właściwości swojego projektu, jak pokazano poniżej -

  • Step 6. W zakładce Biblioteki kliknij ADD EXternal JARs... przycisk.

  • Step 7. Wybierz plik jar avro-1.77.jar pobrałeś.

  • Step 8. Kliknij OK.

Avro z Mavenem

Możesz również wprowadzić bibliotekę Avro do swojego projektu za pomocą Maven. Poniżej podano plik pom.xml dla 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>

Ustawianie ścieżki klasy

Aby pracować z Avro w środowisku Linux, pobierz następujące pliki jar -

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

Skopiuj te pliki do folderu i ustaw ścieżkę klasy na folder w./bashrc plik, jak pokazano poniżej.

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

Avro, będąc narzędziem serializacji opartym na schemacie, akceptuje schematy jako dane wejściowe. Pomimo dostępnych różnych schematów, Avro stosuje własne standardy definiowania schematów. Te schematy opisują następujące szczegóły -

  • typ pliku (nagrywanie domyślnie)
  • lokalizacja zapisu
  • nazwa wpisu
  • pola w rekordzie wraz z odpowiadającymi im typami danych

Korzystając z tych schematów, można przechowywać zserializowane wartości w formacie binarnym przy użyciu mniejszej ilości miejsca. Te wartości są przechowywane bez żadnych metadanych.

Tworzenie schematów Avro

Schemat Avro jest tworzony w formacie dokumentu JavaScript Object Notation (JSON), który jest lekkim tekstowym formatem wymiany danych. Jest tworzony na jeden z następujących sposobów -

  • Ciąg JSON
  • Obiekt JSON
  • Tablica JSON

Example - Poniższy przykład przedstawia schemat, który definiuje dokument w przestrzeni nazw Tutorialspoint, z imieniem Pracownik, z polami zawierającymi nazwy i wiek.

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

W tym przykładzie można zauważyć, że dla każdego rekordu są cztery pola -

  • type - To pole znajduje się pod dokumentem, a także pod polem o nazwie fields.

    • W przypadku dokumentu pokazuje typ dokumentu, zazwyczaj rekord, ponieważ istnieje wiele pól.

    • Gdy jest to pole, typ opisuje typ danych.

  • namespace - To pole zawiera nazwę przestrzeni nazw, w której znajduje się obiekt.

  • name - To pole znajduje się pod dokumentem, a także pod polem o nazwie fields.

    • W przypadku dokumentu opisuje nazwę schematu. Ta nazwa schematu wraz z przestrzenią nazw jednoznacznie identyfikuje schemat w sklepie (Namespace.schema name). W powyższym przykładzie pełna nazwa schematu to Tutorialspoint.Employee.

    • W przypadku pól opisuje nazwę pola.

Prymitywne typy danych Avro

Schemat Avro zawiera prymitywne typy danych, a także złożone typy danych. W poniższej tabeli opisanoprimitive data types z Avro -

Typ danych Opis
zero Null to typ bez wartości.
int 32-bitowa liczba całkowita ze znakiem.
długo 64-bitowa liczba całkowita ze znakiem.
pływak pojedyncza precyzja (32-bitowa) liczba zmiennoprzecinkowa IEEE 754.
podwójnie podwójna precyzja (64-bitowa) liczba zmiennoprzecinkowa IEEE 754.
bajtów sekwencja 8-bitowych bajtów bez znaku.
strunowy Sekwencja znaków Unicode.

Złożone typy danych Avro

Oprócz prymitywnych typów danych Avro zapewnia sześć złożonych typów danych, a mianowicie rekordy, wyliczenia, tablice, mapy, związki i naprawione.

Rekord

Rekordowy typ danych w Avro to zbiór wielu atrybutów. Obsługuje następujące atrybuty -

  • name - Wartość tego pola zawiera nazwę rekordu.

  • namespace - wartość tego pola zawiera nazwę przestrzeni nazw, w której przechowywany jest obiekt.

  • type - Wartość tego atrybutu zawiera typ dokumentu (rekordu) lub typ danych pola w schemacie.

  • fields - To pole zawiera tablicę JSON, która zawiera listę wszystkich pól w schemacie, z których każde ma nazwę i atrybuty typu.

Example

Poniżej podano przykład rekordu.

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

Enum

Wyliczenie to lista elementów w kolekcji, wyliczenie Avro obsługuje następujące atrybuty -

  • name - wartość tego pola zawiera nazwę wyliczenia.

  • namespace - wartość tego pola zawiera ciąg, który kwalifikuje nazwę wyliczenia.

  • symbols - wartość tego pola zawiera symbole wyliczenia jako tablicę nazw.

Example

Poniżej podano przykład wyliczenia.

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

Tablice

Ten typ danych definiuje pole tablicy zawierające pojedyncze elementy atrybutu. Ten atrybut pozycji określa typ elementów w tablicy.

Example

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

Mapy

Typ danych mapy to tablica par klucz-wartość, organizuje dane jako pary klucz-wartość. Klucz do mapy Avro musi być ciągiem. Wartości mapy zawierają typ danych zawartości mapy.

Example

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

Związki

Typ danych unii jest używany, gdy pole ma jeden lub więcej typów danych. Są reprezentowane jako tablice JSON. Na przykład, jeśli pole może mieć wartość typu int lub null, wówczas unia jest reprezentowana jako ["int", "null"].

Example

Poniżej podano przykładowy dokument wykorzystujący związki -

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

Naprawiony

Ten typ danych służy do deklarowania pola o stałym rozmiarze, którego można używać do przechowywania danych binarnych. Ma nazwę pola i dane jako atrybuty. Nazwa zawiera nazwę pola, a rozmiar - rozmiar pola.

Example

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

W poprzednim rozdziale opisaliśmy typ wejścia Avro, czyli schematy Avro. W tym rozdziale wyjaśnimy klasy i metody używane w serializacji i deserializacji schematów Avro.

SpecificDatumWriter Klasa

Ta klasa należy do pakietu org.apache.avro.specific. ImplementujeDatumWriter interfejs, który konwertuje obiekty Java na format serializowany w pamięci.

Konstruktor

S.No. Opis
1 SpecificDatumWriter(Schema schema)

metoda

S.No. Opis
1

SpecificData getSpecificData()

Zwraca implementację SpecificData używaną przez ten moduł zapisujący.

SpecificDatumReader Class

Ta klasa należy do pakietu org.apache.avro.specific. ImplementujeDatumReader interfejs, który odczytuje dane schematu i określa reprezentację danych w pamięci. SpecificDatumReader to klasa obsługująca wygenerowane klasy java.

Konstruktor

S.No. Opis
1

SpecificDatumReader(Schema schema)

Skonstruuj, gdzie schematy pisarza i czytelnika są takie same.

Metody

S.No. Opis
1

SpecificData getSpecificData()

Zwraca zawarte dane SpecificData.

2

void setSchema(Schema actual)

Ta metoda służy do ustawiania schematu modułu zapisującego.

DataFileWriter

Instancje DataFileWrite dla empklasa. Ta klasa zapisuje sekwencję zserializowanych rekordów danych zgodnych ze schematem, wraz ze schematem w pliku.

Konstruktor

S.No. Opis
1 DataFileWriter(DatumWriter<D> dout)

Metody

S.Nr Opis
1

void append(D datum)

Dołącza odniesienie do pliku.

2

DataFileWriter<D> appendTo(File file)

Ta metoda służy do otwierania modułu zapisującego dołączanego do istniejącego pliku.

Data FileReader

Ta klasa zapewnia losowy dostęp do plików zapisanych w DataFileWriter. Dziedziczy klasęDataFileStream.

Konstruktor

S.No. Opis
1 DataFileReader(File file, DatumReader<D> reader))

Metody

S.No. Opis
1

next()

Wczytuje następne odniesienie w pliku.

2

Boolean hasNext()

Zwraca wartość true, jeśli w tym pliku pozostało więcej wpisów.

Class Schema.parser

Ta klasa jest parserem dla schematów w formacie JSON. Zawiera metody do analizowania schematu. To należy doorg.apache.avro pakiet.

Konstruktor

S.No. Opis
1 Schema.Parser()

Metody

S.No. Opis
1

parse (File file)

Analizuje schemat podany w podanym file.

2

parse (InputStream in)

Analizuje schemat podany w podanym InputStream.

3

parse (String s)

Analizuje schemat podany w podanym String.

Interfejs GenricRecord

Ten interfejs zapewnia metody dostępu do pól według nazwy oraz indeksu.

Metody

S.No. Opis
1

Object get(String key)

Zwraca wartość podanego pola.

2

void put(String key, Object v)

Ustawia wartość pola na podstawie jego nazwy.

Klasa GenericData.Record

Konstruktor

S.No. Opis
1 GenericData.Record(Schema schema)

Metody

S.No. Opis
1

Object get(String key)

Zwraca wartość pola o podanej nazwie.

2

Schema getSchema()

Zwraca schemat tego wystąpienia.

3

void put(int i, Object v)

Ustawia wartość pola, biorąc pod uwagę jego pozycję w schemacie.

4

void put(String key, Object value)

Ustawia wartość pola na podstawie jego nazwy.

Schemat Avro można wczytać do programu generując klasę odpowiadającą schematowi lub korzystając z biblioteki parserów. W tym rozdziale opisano, jak czytać schematby generating a class i Serializing dane za pomocą Avr.

Serializacja przez generowanie klasy

Aby serializować dane za pomocą Avro, wykonaj kroki podane poniżej -

  • Napisz schemat Avro.

  • Skompiluj schemat za pomocą narzędzia Avro. Otrzymasz kod Java odpowiadający temu schematowi.

  • Wypełnij schemat danymi.

  • Serializuj go przy użyciu biblioteki Avro.

Definiowanie schematu

Załóżmy, że potrzebujesz schematu z następującymi szczegółami -

Field Nazwa ID wiek wynagrodzenie adres
type Strunowy int int int strunowy

Utwórz schemat Avro, jak pokazano poniżej.

Zapisz to jako 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"}
   ]
}

Kompilowanie schematu

Po utworzeniu schematu Avro należy skompilować utworzony schemat za pomocą narzędzi Avro. avro-tools-1.7.7.jar to słoik zawierający narzędzia.

Składnia do kompilowania schematu Avro

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

Otwórz terminal w folderze domowym.

Utwórz nowy katalog do pracy z Avro, jak pokazano poniżej -

$ mkdir Avro_Work

W nowo utworzonym katalogu utwórz trzy podkatalogi -

  • Pierwsza nazwa schema, aby umieścić schemat.

  • Drugi nazwany with_code_gen, aby umieścić wygenerowany kod.

  • Trzeci nazwany jars, aby umieścić pliki jar.

$ mkdir schema
$ mkdir with_code_gen
$ mkdir jars

Poniższy zrzut ekranu pokazuje, jak twój Avro_work folder powinien wyglądać jak po utworzeniu wszystkich katalogów.

  • Teraz /home/Hadoop/Avro_work/jars/avro-tools-1.7.7.jar jest ścieżką do katalogu, do którego został pobrany plik avro-tools-1.7.7.jar.

  • /home/Hadoop/Avro_work/schema/ jest ścieżką do katalogu, w którym przechowywany jest plik schematu emp.avsc.

  • /home/Hadoop/Avro_work/with_code_gen jest katalogiem, w którym mają być przechowywane wygenerowane pliki klas.

Teraz skompiluj schemat, jak pokazano poniżej -

$ 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

Po skompilowaniu w katalogu docelowym tworzony jest pakiet zgodnie z przestrzenią nazw schematu. W ramach tego pakietu tworzony jest kod źródłowy Java z nazwą schematu. Ten wygenerowany kod źródłowy jest kodem Java danego schematu, który można bezpośrednio wykorzystać w aplikacjach.

Na przykład w tym przypadku pakiet / folder o nazwie tutorialspoint jest tworzony, który zawiera inny folder o nazwie com (ponieważ przestrzeń nazw to tutorialspoint.com) iw nim możesz obserwować wygenerowany plik emp.java. Poniższa migawka przedstawiaemp.java -

Ta klasa jest przydatna do tworzenia danych według schematu.

Wygenerowana klasa zawiera -

  • Konstruktor domyślny i konstruktor sparametryzowany, który akceptuje wszystkie zmienne schematu.
  • Metody ustawiające i pobierające dla wszystkich zmiennych w schemacie.
  • Get (), która zwraca schemat.
  • Metody konstruktora.

Tworzenie i serializacja danych

Przede wszystkim skopiuj wygenerowany plik java używany w tym projekcie do bieżącego katalogu lub zaimportuj go z miejsca, w którym się znajduje.

Teraz możemy napisać nowy plik Java i utworzyć instancję klasy w wygenerowanym pliku (emp), aby dodać dane pracowników do schematu.

Zobaczmy procedurę tworzenia danych zgodnie ze schematem przy użyciu apache Avro.

Krok 1

Utwórz wystąpienie wygenerowanego pliku emp klasa.

emp e1=new emp( );

Krok 2

Korzystając z metod ustawiających, wprowadź dane pierwszego pracownika. Na przykład stworzyliśmy dane pracownika o imieniu Omar.

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

Podobnie wypełnij wszystkie dane pracownika, korzystając z metod ustawiających.

Krok 3

Utwórz obiekt DatumWriter interfejs przy użyciu SpecificDatumWriterklasa. To konwertuje obiekty Java na format serializowany w pamięci. Następujący przykład tworzy wystąpienieSpecificDatumWriter obiekt klasy dla emp klasa.

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

Krok 4

Utwórz instancję DataFileWriter dla empklasa. Ta klasa zapisuje w pliku sekwencję zserializowanych rekordów danych zgodnych ze schematem, wraz z samym schematem. Ta klasa wymagaDatumWriter obiekt, jako parametr konstruktora.

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

Krok 5

Otwórz nowy plik, aby zapisać dane pasujące do danego schematu za pomocą create()metoda. Ta metoda wymaga schematu i ścieżki do pliku, w którym mają być przechowywane dane, jako parametrów.

W poniższym przykładzie schemat jest przekazywany przy użyciu getSchema() metoda, a plik danych jest przechowywany w ścieżce - /home/Hadoop/Avro/serialized_file/emp.avro.

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

Krok 6

Dodaj wszystkie utworzone rekordy do pliku za pomocą append() metoda, jak pokazano poniżej -

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

Przykład - serializacja przez generowanie klasy

Poniższy kompletny program pokazuje, jak serializować dane do pliku za pomocą 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");
   }
}

Przeglądaj katalog, w którym znajduje się wygenerowany kod. W tym przypadku o godzhome/Hadoop/Avro_work/with_code_gen.

In Terminal −

$ cd home/Hadoop/Avro_work/with_code_gen/

In GUI −

Teraz skopiuj i zapisz powyższy program w pliku o nazwie Serialize.java

Skompiluj i wykonaj, jak pokazano poniżej -

$ javac Serialize.java
$ java Serialize

Wynik

data successfully serialized

Jeśli zweryfikujesz ścieżkę podaną w programie, możesz znaleźć wygenerowany plik serializowany, jak pokazano poniżej.

Jak opisano wcześniej, schemat Avro można wczytać do programu, generując klasę odpowiadającą schematowi lub korzystając z biblioteki parserów. W tym rozdziale opisano, jak czytać schematby generating a class i Deserialize dane za pomocą Avro.

Deserializacja poprzez generowanie klasy

Zserializowane dane są przechowywane w pliku emp.avro. Możesz deserializować i czytać go za pomocą Avro.

Postępuj zgodnie z procedurą podaną poniżej, aby deserializować serializowane dane z pliku.

Krok 1

Utwórz obiekt DatumReader interfejs przy użyciu SpecificDatumReader klasa.

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

Krok 2

Utwórz instancję DataFileReader dla empklasa. Ta klasa odczytuje serializowane dane z pliku. WymagaDataumeader obiekt i ścieżka do pliku, w którym istnieją serializowane dane, jako parametry konstruktora.

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

Krok 3

Wydrukuj zdeserializowane dane przy użyciu metod DataFileReader.

  • Plik hasNext() metoda zwróci wartość logiczną, jeśli w programie Reader znajdują się jakieś elementy.

  • Plik next() metoda DataFileReader zwraca dane w Czytniku.

while(dataFileReader.hasNext()){

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

Przykład - deserializacja przez generowanie klasy

Poniższy kompletny program pokazuje, jak deserializować dane w pliku przy użyciu 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);
      }
   }
}

Przejdź do katalogu, w którym znajduje się wygenerowany kod. W tym przypadku o godzhome/Hadoop/Avro_work/with_code_gen.

$ cd home/Hadoop/Avro_work/with_code_gen/

Teraz skopiuj i zapisz powyższy program w pliku o nazwie DeSerialize.java. Skompiluj i wykonaj, jak pokazano poniżej -

$ javac Deserialize.java
$ java Deserialize

Wynik

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

Schemat Avro można wczytać do programu, generując klasę odpowiadającą schematowi lub korzystając z biblioteki parserów. W Avro dane są zawsze przechowywane wraz z odpowiednim schematem. Dlatego zawsze możemy odczytać schemat bez generowania kodu.

W tym rozdziale opisano, jak czytać schemat by using parsers library i do serialize dane za pomocą Avro.

Serializacja przy użyciu biblioteki parserów

Aby serializować dane, musimy odczytać schemat, utworzyć dane zgodnie ze schematem i serializować schemat za pomocą Avro API. Poniższa procedura serializuje dane bez generowania żadnego kodu -

Krok 1

Przede wszystkim przeczytaj schemat z pliku. Aby to zrobić, użyjSchema.Parserklasa. Ta klasa udostępnia metody do analizowania schematu w różnych formatach.

Utwórz wystąpienie Schema.Parser class, przekazując ścieżkę do pliku, w którym przechowywany jest schemat.

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

Krok 2

Utwórz obiekt GenericRecord interfejs, tworząc wystąpienie GenericData.Recordklasa, jak pokazano poniżej. Przekaż utworzony powyżej obiekt schematu do jego konstruktora.

GenericRecord e1 = new GenericData.Record(schema);

Krok 3

Wstaw wartości w schemacie przy użyciu rozszerzenia put() metoda GenericData klasa.

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

Krok 4

Utwórz obiekt DatumWriter interfejs przy użyciu SpecificDatumWriterklasa. Konwertuje obiekty Java na format serializowany w pamięci. Następujący przykład tworzy wystąpienieSpecificDatumWriter obiekt klasy dla emp klasa -

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

Krok 5

Utwórz instancję DataFileWriter dla empklasa. Ta klasa zapisuje zserializowane rekordy danych zgodnych ze schematem, wraz z samym schematem, w pliku. Ta klasa wymagaDatumWriter obiekt, jako parametr konstruktora.

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

Krok 6

Otwórz nowy plik, aby zapisać dane pasujące do danego schematu za pomocą create()metoda. Ta metoda wymaga schematu i ścieżki do pliku, w którym mają być przechowywane dane, jako parametrów.

W poniższym przykładzie schemat jest przekazywany za pomocą getSchema() metoda, a plik danych jest przechowywany w ścieżce

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

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

Krok 7

Dodaj wszystkie utworzone rekordy do pliku za pomocą append( ) metoda, jak pokazano poniżej.

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

Przykład - serializacja przy użyciu parserów

Poniższy kompletny program pokazuje, jak serializować dane za pomocą parserów -

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

Przejdź do katalogu, w którym znajduje się wygenerowany kod. W tym przypadku o godzhome/Hadoop/Avro_work/without_code_gen.

$ cd home/Hadoop/Avro_work/without_code_gen/

Teraz skopiuj i zapisz powyższy program w pliku o nazwie Serialize.java. Skompiluj i wykonaj, jak pokazano poniżej -

$ javac Serialize.java
$ java Serialize

Wynik

data successfully serialized

Jeśli zweryfikujesz ścieżkę podaną w programie, możesz znaleźć wygenerowany plik serializowany, jak pokazano poniżej.

Jak wspomniano wcześniej, schemat Avro można wczytać do programu, generując klasę odpowiadającą schematowi lub korzystając z biblioteki parserów. W Avro dane są zawsze przechowywane wraz z odpowiednim schematem. Dlatego zawsze możemy odczytać serializowany element bez generowania kodu.

W tym rozdziale opisano, jak czytać schemat using parsers library i Deserializing dane za pomocą Avro.

Deserializacja przy użyciu biblioteki parserów

Zserializowane dane są przechowywane w pliku mydata.txt. Możesz deserializować i czytać go za pomocą Avro.

Postępuj zgodnie z procedurą podaną poniżej, aby deserializować serializowane dane z pliku.

Krok 1

Przede wszystkim przeczytaj schemat z pliku. Aby to zrobić, użyjSchema.Parserklasa. Ta klasa udostępnia metody do analizowania schematu w różnych formatach.

Utwórz wystąpienie Schema.Parser class, przekazując ścieżkę do pliku, w którym przechowywany jest schemat.

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

Krok 2

Utwórz obiekt DatumReader interfejs przy użyciu SpecificDatumReader klasa.

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

Krok 3

Utwórz instancję DataFileReaderklasa. Ta klasa odczytuje serializowane dane z pliku. WymagaDatumReader obiekt i ścieżka do pliku, w którym istnieją serializowane dane, jako parametry konstruktora.

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

Krok 4

Wydrukuj zdeserializowane dane przy użyciu metod DataFileReader.

  • Plik hasNext() metoda zwraca wartość logiczną, jeśli w programie Reader znajdują się jakieś elementy.

  • Plik next() metoda DataFileReader zwraca dane w Czytniku.

while(dataFileReader.hasNext()){

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

Przykład - deserializacja przy użyciu biblioteki parserów

Poniższy kompletny program pokazuje, jak deserializować zserializowane dane przy użyciu biblioteki 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");
   }
}

Przejdź do katalogu, w którym znajduje się wygenerowany kod. W tym przypadku jest tohome/Hadoop/Avro_work/without_code_gen.

$ cd home/Hadoop/Avro_work/without_code_gen/

Teraz skopiuj i zapisz powyższy program w pliku o nazwie DeSerialize.java. Skompiluj i wykonaj, jak pokazano poniżej -

$ javac Deserialize.java
$ java Deserialize

Wynik

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