Vodič za Apache Avro

1. Pregled

Serijalizacija podataka je tehnika pretvaranja podataka u binarni ili tekstualni format. U tu svrhu dostupno je više sustava. Apache Avro jedan je od onih sustava za serializaciju podataka.

Avro je jezično neovisna knjižnica za serializaciju podataka zasnovana na shemi. Koristi shemu za obavljanje serializacije i deserializacije. Štoviše, Avro koristi JSON format za određivanje strukture podataka koja ga čini moćnijim.

U ovom uputstvu istražit ćemo više o postavljanju Avra, Java API-ju za obavljanje serializacije i usporedbi Avra ​​s drugim sustavima za serializaciju podataka.

Usredotočit ćemo se prvenstveno na stvaranje sheme koja je osnova cijelog sustava.

2. Apač Avro

Avro je jezično neovisna knjižnica za serializaciju. Da bi to učinio, Avro koristi shemu koja je jedna od glavnih komponenti. To shemu pohranjuje u datoteku za daljnju obradu podataka.

Avro je najprikladniji za obradu velikih podataka. Prilično je popularan u svijetu Hadoop-a i Kafke zbog brže obrade.

Avro stvara podatkovnu datoteku u kojoj čuva podatke zajedno sa shemom u odjeljku s metapodacima. Iznad svega, pruža bogatu strukturu podataka što ga čini popularnijim od ostalih sličnih rješenja.

Da bismo koristili Avro za serializaciju, moramo slijediti korake navedene u nastavku.

3. Izjava o problemu

Počnimo s definiranjem klase tzv AvroHttRequest koje ćemo koristiti za naše primjere. Klasa sadrži primitivne kao i složene atribute tipa:

klasa AvroHttpRequest {private long requestTime; privatni ClientIdentifier clientIdentifier; privatni Popis workerNames; privatno Aktivno aktivno; } 

Ovdje, requestTime je primitivna vrijednost. ClientIdentifier je druga klasa koja predstavlja složeni tip. Također imamo ime zaposlenika što je opet složen tip. Aktivan je popis koji opisuje je li dani popis zaposlenika aktivan ili ne.

Naš je cilj serializirati i desserializirati AvroHttRequest razred koristeći Apache Avro.

4. Avro tipovi podataka

Prije nego što nastavimo dalje, razgovarajmo o vrstama podataka koje podržava Avro.

Avro podržava dvije vrste podataka:

  • Primitivni tip: Avro podržava sve primitivne tipove. Primitivni naziv tipa koristimo za definiranje vrste datog polja. Na primjer, vrijednost koja sadrži a Niz treba deklarirati kao {“type”: “string”} u Shemi
  • Kompleksni tip: Avro podržava šest vrsta složenih tipova: zapisi, popisi, nizovi, karte, unije i fiksni

Na primjer, u našoj izjavi o problemu, ClientIdentifier je rekord.

U tom slučaju shema za ClientIdentifier treba izgledati ovako:

{"type": "record", "name": "ClientIdentifier", "namespace": "com.baeldung.avro", "polja": [{"name": "hostName", "type": "string" }, {"name": "ipAddress", "type": "string"}]}

5. Korištenje Avra

Za početak, dodajmo ovisnosti Mavena koje ćemo trebati pom.xml datoteka.

Trebali bismo uključiti sljedeće ovisnosti:

  • Apache Avro - temeljne komponente
  • Prevoditelj - Apache Avro kompajleri za Avro IDL i Avro Specific Java Java APIT
  • Alati - što uključuje Apache Avro alate i uslužne programe naredbenog retka
  • Dodatak Apache Avro Maven za Maven projekte

Za ovu lekciju koristimo verziju 1.8.2.

Međutim, uvijek se savjetuje da na Maven Centralu pronađete najnoviju verziju:

 org.apache.avro avro-compiler 1.8.2 org.apache.avro avro-maven-plugin 1.8.2 

Nakon dodavanja maven ovisnosti, sljedeći će koraci biti:

  • Stvaranje sheme
  • Čitanje sheme u našem programu
  • Serijaliziranje naših podataka pomoću Avra
  • Napokon, de-serializirajte podatke

6. Stvaranje sheme

Avro opisuje svoju shemu koristeći JSON format. Postoje uglavnom četiri atributa za određenu Avro shemu:

  • Tip- koji opisuje tip sheme bilo da je to složeni tip ili primitivna vrijednost
  • Prostor imena koji opisuje prostor imena kojem pripada navedena shema
  • Ime - naziv Sheme
  • Polja- koji govori o poljima povezanim s danom shemom. Polja mogu biti primitivnog, ali i složenog tipa.

Jedan od načina stvaranja sheme je pisanje JSON reprezentacije, kao što smo vidjeli u prethodnim odjeljcima.

Također možemo stvoriti shemu pomoću SchemaBuilder što je nesumnjivo bolji i učinkovitiji način stvaranja.

6.1. SchemaBuilder Korisnost

Razred org.apache.avro.SchemaBuilder je korisno za stvaranje sheme.

Prije svega, kreirajmo shemu za ClientIdentifier:

Shema clientIdentifier = SchemaBuilder.record ("ClientIdentifier") .namespace ("com.baeldung.avro") .fields (). RequiredString ("hostName"). RequiredString ("ipAddress") .endRecord ();

Sada, iskoristimo ovo za stvaranje avroHttpRequest shema:

Shema avroHttpRequest = SchemaBuilder.record ("AvroHttpRequest") .namespace ("com.baeldung.avro"). Fields (). RequiredLong ("requestTime") .name ("clientIdentifier") .type (clientIdentifier) ​​.noDefault (). ime ("imena zaposlenika") .type () .array () .items () .stringType () .arrayDefault (null) .name ("active") .type () .enumeration ("Active") .symbols ("DA "," NE ") .noDefault () .endRecord ();

Ovdje je važno napomenuti da smo dodijelili clientIdentifier kao tip za clientIdentifier polje. U ovom slučaju, clientIdentifier koja se koristi za definiranje tipa ista je shema koju smo stvorili prije.

Kasnije možemo primijeniti toString metoda za dobivanje JSON struktura Shema.

Datoteke sheme spremaju se pomoću ekstenzije .avsc. Spremimo generiranu shemu u “Src / main / resources / avroHttpRequest-schema.avsc” datoteka.

7. Čitanje sheme

Čitanje sheme je manje više važno stvaranje Avro klasa za zadanu shemu. Jednom kada su stvorene Avro klase, možemo ih koristiti za serializaciju i deserializaciju objekata.

Postoje dva načina za stvaranje Avro klasa:

  • Programsko generiranje Avro klasa: Predavanja se mogu generirati pomoću SchemaCompiler. Postoji nekoliko API-ja koje možemo koristiti za generiranje Java klasa. Kod za generatorske satove možemo pronaći na GitHubu.
  • Korištenje Mavena za generiranje klasa

Imamo jedan dodatak maven koji dobro obavlja svoj posao. Moramo uključiti dodatak i pokrenuti mvn čista instalacija.

Dodajmo dodatak našem pom.xml datoteka:

 org.apache.avro avro-maven-plugin $ {avro.version} sheme generiraj-izvor protokol sheme idl-protokol $ {project.basedir} / src / main / resources / $ {project.basedir} / src / main / java / 

8. Serijalizacija i deserijalizacija s Avro

Kako smo završili s generiranjem sheme, nastavimo istraživati ​​dio serializacije.

Postoje dva formata za serializaciju podataka koje Avro podržava: JSON format i Binarni format.

Prvo ćemo se usredotočiti na JSON format, a zatim ćemo razgovarati o binarnom formatu.

Prije nego što nastavimo dalje, trebali bismo proći kroz nekoliko ključnih sučelja. Sučelja i klase u nastavku možemo koristiti za serializaciju:

DatumWriter: Ovo bismo trebali koristiti za pisanje podataka na danoj shemi. Koristit ćemo SpecificDatumWriter implementacija u našem primjeru, međutim, DatumWriter ima i druge implementacije. Ostale implementacije su GenericDatumWriter, Json.Writer, ProtobufDatumWriter, ReflectDatumWriter, ThriftDatumWriter.

Davač: Kodiranje se koristi ili definira format kao što je prethodno spomenuto. EncoderFactory nudi dvije vrste kodera, binarni koder i JSON koder.

DatumReader: Jedno sučelje za de-serializaciju. Opet, dobio je više implementacija, ali mi ćemo ih koristiti SpecificDatumReader u našem primjeru. Ostale implementacije su- GenericDatumReader, Json.ObjectReader, Json.Reader, ProtobufDatumReader, ReflectDatumReader, ThriftDatumReader.

Dekoder: Dekoder se koristi tijekom uklanjanja serializacije podataka. Decoderfactory nudi dvije vrste dekodera: binarni dekoder i JSON dekoder.

Dalje, pogledajmo kako se u Avru događaju serializacija i de-serializacija.

8.1. Serijalizacija

Uzet ćemo primjer AvroHttpRequest razreda i pokušajte ga serializirati pomoću Avra.

Prije svega, neka je serializiramo u JSON formatu:

javni bajt [] serealizeAvroHttpRequestJSON (zahtjev za AvroHttpRequest) {DatumWriter Writer = novi SpecificDatumWriter (AvroHttpRequest.class); bajt [] podaci = novi bajt [0]; ByteArrayOutputStream stream = novi ByteArrayOutputStream (); Kodiranje jsonEncoder = null; isprobajte {jsonEncoder = EncoderFactory.get (). jsonEncoder (AvroHttpRequest.getClassSchema (), stream); Writer.write (zahtjev, jsonEncoder); jsonEncoder.flush (); podaci = stream.toByteArray (); } catch (IOException e) {logger.error ("Pogreška serializacije:" + e.getMessage ()); } vratiti podatke; } 

Pogledajmo test slučaja za ovu metodu:

@Test public void whenSerialized_UsingJSONEncoder_ObjectGetsSerialized () {byte [] data = serealizer.serealizeAvroHttpRequestJSON (zahtjev); assertTrue (Objects.nonNull (podaci)); assertTrue (data.length> 0); }

Ovdje smo koristili jsonEncoder metoda i prenošenje sheme na nju.

Ako smo željeli koristiti binarni koder, moramo zamijeniti jsonEncoder () metoda sa binaryEncoder ():

Kodiranje jsonEncoder = EncoderFactory.get (). BinaryEncoder (stream, null);

8.2. Deserijalizacija

Da bismo to učinili, poslužit ćemo se gore spomenutim DatumReader i Dekoder sučelja.

Kao što smo koristili EncoderFactory da biste dobili Koder, slično ćemo koristiti DecoderFactory dobiti a Dekoder objekt.

Deserializiramo podatke pomoću JSON formata:

javni AvroHttpRequest deSerealizeAvroHttpRequestJSON (bajt [] podaci) {DatumReader čitač = novi SpecificDatumReader (AvroHttpRequest.class); Dekoder dekoder = null; pokušajte {decoder = DecoderFactory.get (). jsonDecoder (AvroHttpRequest.getClassSchema (), novi String (podaci)); vratiti čitač.read (null, dekoder); } catch (IOException e) {logger.error ("Pogreška deserijalizacije:" + e.getMessage ()); }} 

I da vidimo test slučaj:

@Test public void whenDeserializeUsingJSONDecoder_thenActualAndExpectedObjectsAreEqual () {byte [] data = serealizer.serealizeAvroHttpRequestJSON (zahtjev); AvroHttpRequest actualRequest = deSerealizer .deSerealizeAvroHttpRequestJSON (podaci); assertEquals (actualRequest, zahtjev); assertTrue (actualRequest.getRequestTime () .equals (request.getRequestTime ())); }

Slično tome, možemo koristiti binarni dekoder:

Dekoder dekoder = DecoderFactory.get (). BinaryDecoder (podaci, null);

9. Zaključak

Apache Avro posebno je koristan u radu s velikim podacima. Nudi serializaciju podataka u binarnom kao i JSON formatu koji se može koristiti prema slučaju korištenja.

Avro postupak serializacije brži je, a uz to je i prostorno učinkovit. Avro ne čuva podatke o tipu polja uz svako polje; umjesto toga, on stvara metapodatke u shemi.

I na kraju, ali ne najmanje važno, Avro ima sjajan povez sa širokim rasponom programskih jezika, što mu daje prednost.

Kao i uvijek, kod se može pronaći na GitHub-u.