Protokolbuffere | |
---|---|
Type | dataserialiseringsformat |
Udvikler | |
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] .
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.
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.
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.
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] .
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:
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 .
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 | 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 |