Guide til Apache Avro

1. Oversikt

Dataserialisering er en teknikk for å konvertere data til binært eller tekstformat. Det er flere systemer tilgjengelig for dette formålet. Apache Avro er et av disse dataserialiseringssystemene.

Avro er et språkuavhengig, skjemabasert databaseringsbibliotek. Den bruker et skjema for å utføre serialisering og deserialisering. Videre bruker Avro et JSON-format for å spesifisere datastrukturen som gjør den kraftigere.

I denne opplæringen vil vi utforske mer om Avro-oppsett, Java API for å utføre serialisering og en sammenligning av Avro med andre dataserialiseringssystemer.

Vi vil først og fremst fokusere på skjemaoppretting som er basen i hele systemet.

2. Apache Avro

Avro er et språkuavhengig serieiseringsbibliotek. For å gjøre dette bruker Avro et skjema som er en av kjernekomponentene. Den lagrer skjemaet i en fil for videre databehandling.

Avro passer best for Big Data-behandling. Det er ganske populært i Hadoop og Kafka-verdenen for raskere behandling.

Avro oppretter en datafil der den lagrer data sammen med skjemaet i metadataseksjonen. Fremfor alt gir den en rik datastruktur som gjør den mer populær enn andre lignende løsninger.

For å bruke Avro til serialisering, må vi følge trinnene nevnt nedenfor.

3. Problemstilling

La oss starte med å definere en klasse som heter AvroHttRequest som vi vil bruke til eksemplene våre. Klassen inneholder både primitive og komplekse attributter:

klasse AvroHttpRequest {privat lang forespørselstid; private ClientIdentifier clientIdentifier; private List medarbeidernavn privat Aktiv aktiv; } 

Her, requestTime er en primitiv verdi. ClientIdentifier er en annen klasse som representerer en kompleks type. Vi har også ansattes navn som igjen er en kompleks type. Aktiv er en enum for å beskrive om den gitte listen over ansatte er aktiv eller ikke.

Vårt mål er å serieisere og avserialisere AvroHttRequest klasse ved hjelp av Apache Avro.

4. Avro-datatyper

Før vi fortsetter, la oss diskutere datatypene som støttes av Avro.

Avro støtter to typer data:

  • Primitiv type: Avro støtter alle primitive typer. Vi bruker primitivt navn for å definere en type av et gitt felt. For eksempel en verdi som har en String skal erklæres som {“type”: “string”} i skjemaet
  • Kompleks type: Avro støtter seks typer komplekse typer: poster, enums, arrays, maps, unions and fixed

For eksempel i vår problemstilling, ClientIdentifier er en rekord.

I så fall skjema for ClientIdentifier skal se ut som:

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

5. Bruke Avro

Til å begynne med, la oss legge til Maven-avhengighetene vi trenger til våre pom.xml fil.

Vi bør inkludere følgende avhengigheter:

  • Apache Avro - kjernekomponenter
  • Compiler - Apache Avro Compilers for Avro IDL og Avro Specific Java APIT
  • Verktøy - som inkluderer Apache Avro kommandolinjeverktøy og verktøy
  • Apache Avro Maven Plugin for Maven-prosjekter

Vi bruker versjon 1.8.2 for denne opplæringen.

Det anbefales imidlertid alltid å finne den nyeste versjonen på Maven Central:

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

Etter at du har lagt til avhengighetsavhengigheter, vil de neste trinnene være:

  • Skjemaoppretting
  • Leser skjemaet i programmet vårt
  • Serialisering av dataene våre ved hjelp av Avro
  • Til slutt avserialiserer du dataene

6. Oppretting av skjema

Avro beskriver skjemaet ved hjelp av et JSON-format. Det er hovedsakelig fire attributter for et gitt Avro-skjema:

  • Type- som beskriver typen skjema, enten den er kompleks eller primitiv verdi
  • Navneplass- som beskriver navneområdet der det gitte skjemaet tilhører
  • Navn - navnet på skjemaet
  • Enger- som forteller om feltene knyttet til et gitt skjema. Felt kan være av både primitiv og kompleks type.

En måte å lage skjemaet på er å skrive JSON-representasjonen, slik vi så i de forrige avsnittene.

Vi kan også lage et skjema ved hjelp av SchemaBuilder som unektelig er en bedre og effektiv måte å lage den på.

6.1. SchemaBuilder Nytte

Klassen org.apache.avro.SchemaBuilder er nyttig for å lage skjemaet.

La oss først lage skjemaet for ClientIdentifier:

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

La oss nå bruke dette til å lage en avroHttpRequest skjema:

Schema avroHttpRequest = SchemaBuilder.record ("AvroHttpRequest"). Navneplass ("com.baeldung.avro") .fields (). RequiredLong ("requestTime") .name ("clientIdentifier") .type (clientIdentifier) ​​.noDefault (). navn ("ansattnavn") .type () .array () .items () .stringType () .arrayDefault (null) .navn ("aktiv") .type () .oppregning ("Aktiv"). symboler ("YES "," NO ") .noDefault () .endRecord ();

Det er viktig å merke seg her at vi har tildelt clientIdentifier som typen for clientIdentifier felt. I dette tilfellet, clientIdentifier brukes til å definere type er det samme skjemaet vi opprettet før.

Senere kan vi bruke toString metode for å få JSON struktur av Skjema.

Skjemafiler lagres ved hjelp av .avsc-utvidelsen. La oss lagre vårt genererte skjema til “Src / main / resources / avroHttpRequest-schema.avsc” fil.

7. Lese skjemaet

Å lese et skjema handler mer eller mindre om lage Avro-klasser for det gitte skjemaet. Når Avro-klasser er opprettet, kan vi bruke dem til å serieisere og deserialisere objekter.

Det er to måter å lage Avro-klasser på:

  • Programmerer genererende Avro-klasser: Klasser kan genereres ved hjelp av SchemaCompiler. Det er et par APIer som vi kan bruke til å generere Java-klasser. Vi kan finne koden for generasjonsklasser på GitHub.
  • Bruker Maven til å generere klasser

Vi har ett maven-plugin som gjør jobben bra. Vi må ta med pluginet og kjøre mvn ren installasjon.

La oss legge til plugin til vår pom.xml fil:

 org.apache.avro avro-maven-plugin $ {avro.version} skjemaer genererer-kilder skjema protokoll idl-protokoll $ {project.basedir} / src / main / resources / $ {project.basedir} / src / main / java / 

8. Serialisering og deserialisering med Avro

Når vi er ferdige med å generere skjemaet, la oss fortsette å utforske serialiseringsdelen.

Det er to dataserialiseringsformater som Avro støtter: JSON-format og binært format.

Først vil vi fokusere på JSON-formatet og deretter diskutere det binære formatet.

Før vi går videre, bør vi gå gjennom noen viktige grensesnitt. Vi kan bruke grensesnittene og klassene nedenfor for serialisering:

DatumWriter: Vi bør bruke dette til å skrive data om et gitt skjema. Vi bruker SpecificDatumWriter implementering i vårt eksempel, DatumWriter har andre implementeringer også. Andre implementeringer er GenericDatumWriter, Json.Writer, ProtobufDatumWriter, ReflectDatumWriter, ThriftDatumWriter.

Koder: Encoder brukes eller definerer formatet som tidligere nevnt. EncoderFactory gir to typer kodere, binær koderen og JSON-koderen.

DatumReader: Enkelt grensesnitt for avserialisering. Igjen, den har flere implementeringer, men vi skal bruke SpecificDatumReader i vårt eksempel. Andre implementeringer er- GenericDatumReader, Json.ObjectReader, Json.Reader, ProtobufDatumReader, ReflectDatumReader, ThriftDatumReader.

Dekoder: Dekoder brukes mens de-serialisere dataene. Dekoderfabrikk gir to typer dekodere: binær dekoder og JSON dekoder.

La oss deretter se hvordan serialisering og avserialisering skjer i Avro.

8.1. Serialisering

Vi tar eksemplet på AvroHttpRequest klasse og prøv å serieisere den ved hjelp av Avro.

Først av alt, la oss serieisere det i JSON-format:

offentlig byte [] serealizeAvroHttpRequestJSON (AvroHttpRequest forespørsel) {DatumWriter forfatter = ny SpecificDatumWriter (AvroHttpRequest.class); byte [] data = ny byte [0]; ByteArrayOutputStream stream = ny ByteArrayOutputStream (); Koder jsonEncoder = null; prøv {jsonEncoder = EncoderFactory.get (). jsonEncoder (AvroHttpRequest.getClassSchema (), stream); writer.write (forespørsel, jsonEncoder); jsonEncoder.flush (); data = stream.toByteArray (); } fange (IOException e) {logger.error ("Serialiseringsfeil:" + e.getMessage ()); } returnere data; } 

La oss ta en titt på en testtilfelle for denne metoden:

@Test offentlig ugyldig nårSerialized_UsingJSONEncoder_ObjectGetsSerialized () {byte [] data = serealizer.serealizeAvroHttpRequestJSON (forespørsel); assertTrue (Objects.nonNull (data)); assertTrue (data.length> 0); }

Her har vi brukt jsonEncoder metode og overføre skjemaet til den.

Hvis vi ønsket å bruke en binær kode, må vi bytte ut jsonEncoder () metode med binaryEncoder ():

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

8.2. Deserialisering

For å gjøre dette bruker vi ovennevnte DatumReader og Dekoder grensesnitt.

Som vi brukte EncoderFactory å få en Koder, på samme måte vil vi bruke DekoderFabrikk å få en Dekoder gjenstand.

La oss avserialisere dataene ved hjelp av JSON-format:

offentlig AvroHttpRequest deSerealizeAvroHttpRequestJSON (byte [] data) {DatumReader reader = new SpecificDatumReader (AvroHttpRequest.class); Dekoder dekoder = null; prøv {decoder = DecoderFactory.get (). jsonDecoder (AvroHttpRequest.getClassSchema (), ny streng (data)); return reader.read (null, dekoder); } fange (IOException e) {logger.error ("Deserialiseringsfeil:" + e.getMessage ()); }} 

Og la oss se testsaken:

@Test offentlig ugyldig nårDeserializeUsingJSONDecoder_thenActualAndExpectedObjectsAreEqual () {byte [] data = serealizer.serealizeAvroHttpRequestJSON (forespørsel); AvroHttpRequest actualRequest = deSerealizer .deSerealizeAvroHttpRequestJSON (data); assertEquals (faktisk forespørsel, forespørsel); assertTrue (actualRequest.getRequestTime () .equals (request.getRequestTime ())); }

På samme måte kan vi bruke en binær dekoder:

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

9. Konklusjon

Apache Avro er spesielt nyttig når du arbeider med store data. Den tilbyr dataserialisering i både binært og JSON-format som kan brukes i henhold til brukssaken.

Avro-serialiseringsprosessen er raskere, og den er også plasseffektiv. Avro beholder ikke felttypeinformasjonen med hvert felt; i stedet skaper det metadata i et skjema.

Sist men ikke minst har Avro en flott binding med et bredt spekter av programmeringsspråk, noe som gir den et forsprang.

Som alltid kan koden bli funnet på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found