Protokolbuffere

Protokolbuffere
Type dataserialiseringsformat
Udvikler Google
Operativ system Ethvert OS
Første udgave 7. juli 2008
Hardware platform Cross-platform
nyeste version
Stat nuværende
Licens BSD
Internet side developers.google.com/pre...

Protocol Buffers  er en struktureret dataserialiseringsprotokol ( overførsel ) foreslået af Google som et effektivt binært alternativ til XML -tekstformatet . Udviklerne rapporterer, at protokolbuffere er enklere, mindre og hurtigere end XML , da de overfører binære data, der er optimeret til den mindste beskedstørrelse [2] .

Generel information

Som udviklerne har udtænkt, skal datastrukturen først beskrives, som derefter kompileres i klasser. Sammen med klasserne kommer kode til at serialisere dem i et kompakt repræsentationsformat. Læsning og skrivning af data er tilgængelig i programmeringssprog på højt niveau som Java , C++ eller Python .

I 2010 skiftede Twitter -backend til Protocol Buffers. Ifølge udviklerne af Twitter ville en database med en billion tweets i XML fylde ti petabyte i stedet for én. [3]

Ifølge Google , protokolbuffere vs. XML : [2]

Protokolbuffere er ikke beregnet til at blive læst af brugeren og er i binært format. For at deserialisere data skal du bruge en separat .proto -fil, der definerer meddelelsesformatet.

Protokolformat

Generelt er formatet en kodet sekvens af felter, der består af en nøgle og en værdi. Nøglen er det nummer, der er defineret for hvert meddelelsesfelt i protofilen. Hvert felt er indledt med et fælles kodet varintfeltnummer og felttype. Hvis typen er en streng ( string), en vedhæftet meddelelse, en gentagende meddelelse eller et sæt bytes ( bytes), så følger størrelsen af ​​dataene i varint-format. Dernæst kommer værdien svarende til feltet (data) [4] .

Et tal i varintformat ( int32og int64) er kodet til en sekvens af bytes, hvor alle undtagen de sidste bytes har den mest signifikante bit ( MSB ) sat til 1. Når den konverteres til standardrepræsentation, kasseres den mest signifikante bit af hver byte, og de resterende 7-bit komponenter er forbundet med hinanden, den anden i omvendt rækkefølge [4] . 8-bit varint-formatet blev valgt for at reducere pakkestørrelsen ved transmission af små tal. Så hvis tallet er mindre end 128, tager det kun 1 byte. Dog vil tal tæt på det maksimalt mulige fylde mere end i det almindelige format. For eksempel er den maksimale værdi, der kan gemmes i 8 bytes i varint-format, 10 bytes. Negative tal i varintformat har altid den største størrelse, afhængigt af typen, da den mest signifikante bit af det signerede tal er sat til 1.

Problemet med at indkode negative tal blev løst ved hjælp af ZigZag ( sint32og sint64) algoritmen, hvis essens er at overføre fortegnsbitten fra den høje orden til den lave. ZigZag-kodning antager, at positive og negative tal vil veksle med hinanden, når den kodede værdi stiger. I dette tilfælde vil lige tal være positive, og ulige tal vil være negative.

Lad value - den oprindelige værdi, og N - bitdybden af ​​datatypen for den oprindelige værdi, og encoded_value - værdien kodet af ZigZag-algoritmen, så kan kodningen skrives ved hjælp af udtrykket i C-sprog :

kodet_værdi = ( værdi << 1 ) ^ ( værdi >> ( N - 1 ));

Det skal bemærkes, at den anden skiftoperation er et aritmetisk skift, det vil sige, når et negativt tal forskydes til højre, fyldes de høje bits med enere, ikke nuller (fortegnsbitskift).

Afkodning udføres på en mere kompliceret måde: XORing af den kodede værdi flyttet med 1 til højre for at fjerne fortegnsbitten, og fortegnsbitten opnået fra det kodede tal, projiceret på alle bits ved at gange med den maksimale værdi for Nbits. Således overføres fortegnsbitten fra den mindst signifikante bit til den mest signifikante:

uvalue = (( kodet_værdi & 1 ) * MAX_VALUE ( N )) ^ ( kodet_værdi >> 1 );

Værdien MAX_VALUE(N)svarer til værdien med Ncifrene fyldt med enere (f.eks. 0xffffffffved N=32). Således vil multiplikation af den mindst signifikante bit sat til 1 med dette tal svare til værdien -1 i den signerede datatype. I C skal der foretages afkodning for værdier encoded_valueog uvalueen usigneret type, og derefter skal værdien uvaluekonverteres til en fortegnstype uden at ændre bitrepræsentationen.

Alle numeriske værdier, undtagen fixed64, sfixed64og double, er kodet i protokollen i varint-formatet.

Eksempler på brug

For at definere strukturen af ​​de serialiserede data er det nødvendigt at oprette en .proto -fil med kildekoden til denne struktur. Nedenfor er et eksempel på en .proto -fil til version 2 af Protocol Buffers, som beskriver oplysninger om bilen: mærke, karrosseritype, farve, fremstillingsår og oplysninger om tidligere ejere.

meddelelse Bil { nødvendig streng model = 1 ; enum BodyType { sedan = 0 ; hatchback = 1 ; SUV = 2 ; } påkrævet BodyType type = 2 [ standard = sedan ]; valgfri strengfarve = 3 ; _ påkrævet int32 år = 4 ; besked Ejer { påkrævet strengnavn = 1 ; _ påkrævet streng efternavn = 2 ; påkrævet int64 -driverlicens = 3 ; } gentaget Ejer forrigeEjer = 5 ; }

Efter at filen med den ønskede datastruktur er blevet oprettet, skal du kompilere den med en compiler til dit programmeringssprog for at generere en klasse til at få adgang til disse data. Denne klasse vil indeholde de enkleste adgangsmetoder for alle get/set type felter, såvel som metoder til at serialisere og deserialisere din datastruktur til/fra et byte-array.

Det er bemærkelsesværdigt, at du kan tilføje nye felter til en allerede oprettet datastruktur uden at miste kompatibiliteten med den tidligere version: Når du analyserer gamle poster, vil nye felter simpelthen blive ignoreret.

Implementering

I øjeblikket har Google lavet compilere til programmeringssprog: C++ , Java , Python , Go , C# , Objective C , JavaScript [5] . Men der er en række tredjepartsprojekter, der har skabt compilere til følgende programmeringssprog: Action Script , C , C#, Clojure , Common Lisp , D , Erlang , Go, Haskell , Haxe , JavaScript, Lua , Matlab , Mercury , Objective C, Swift .OCaml , Perl , PHP , Python, Ruby , Rust , Scala , Visual Basic , Delphi [6] .

Implementering til C-sprog

For at bruge protokollen i C -sproget uden tredjepartsbiblioteker, skal du enten bruge inserts i C++-sproget, hvis sådanne understøttes af den anvendte compiler, eller pakke den genererede kode til C++ i form af biblioteker. Hvis sådanne muligheder ikke er egnede, er følgende kodegeneratorer kendt:

  • protobuf-c (ingen understøttelse af hukommelsesallokeringsfejl, men du kan bruge dine egne hukommelsesallokeringsmekanismer);
  • nanopb (optimeret til lavt hukommelsesforbrug);
  • protobuf-embedded-c (arkiveret projekt).

Alternative protokoller

Det mest højtydende alternativ er FlatBuffers- biblioteket., som giver dig adgang til serialiserede data uden at kopiere dem i dele til separate hukommelsesområder. I overensstemmelse hermed transmitteres dataene i samme form, som de bruges, og derfor øges mængden af ​​transmitterede data.

Apache Avro- projektadskiller sig ved, at det ikke kræver kodegenerering, når dataskemaet ændres, når det bruges i dynamisk indtastede sprog, og selve skemaet er beskrevet i JSON-format .

Sammenligning med Apache Thrift

Nøglefunktionerne ved Apache Thrift er evnen til at videregive associative arrays, lister og sæt, samt indbygget understøttelse af fjernprocedurekald [7] .

Protokolbuffere Apache sparsommelighed
Udvikler Google Facebook, Apache
Understøttede sprog C++, Dart, Go, Java, Python, Ruby, C#, Objective C, JavaScript og PHP [8] C++, Java, JavaScript, Python, PHP, XSD, Ruby, C#, Perl, Objective C, Erlang, Smalltalk, OCaml og Haskell
Udgående formater Binær Binær, JSON
Simple typer bool, 32/64-bit heltal, float, dobbelt, streng, bytesekvens. Gentagne egenskaber fungerer som lister. bool, byte, 16/32/64-bit heltal, dobbelt, streng, bytesekvens, kort<t1,t2>, liste<t>, sæt<t>.
Konstanter Ikke Ja
Komposit type Besked Struktur
Undtagelser Ikke Ja
Dokumentation godt sølle
Licens BSD stil Apache
Udvidelser af komposittype Ja Ikke

Noter

  1. Udgivelse 21.8 - 2022.
  2. 1 2 Developer Guide - Protocol Buffers Arkiveret 11. september 2014 på Wayback Machine // Google Developers, 2. april 2012.
  3. Twitter løser sin dataformateringsudfordring - Computerworld . Dato for adgang: 6. januar 2011. Arkiveret fra originalen 17. oktober 2010.
  4. ↑ 12 Kodning | Protokolbuffere | Google Developers  (engelsk) . Google udviklere. Hentet 11. oktober 2017. Arkiveret fra originalen 5. september 2017.
  5. API-reference - Protokolbuffere - Google-kode . Hentet 22. maj 2017. Arkiveret fra originalen 15. juli 2017.
  6. Tredjeparts-tilføjelser til protokolbuffere
  7. Thrift vs Protocol Bufffers vs JSON Arkiveret 7. november 2015 på Wayback Machine , MirthLab LLC, 2009
  8. API-reference | Protokolbuffere  . _ Google udviklere. Hentet 4. marts 2019. Arkiveret fra originalen 10. april 2019.

Links