Protokollbuffertar

Protokollbuffertar
Sorts dataserialiseringsformat
Utvecklaren Google
Operativ system Vilket operativsystem som helst
Första upplagan 7 juli 2008
Hårdvaruplattform Cross-plattform
senaste versionen
stat nuvarande
Licens BSD
Hemsida developers.google.com/pre...

Protocol Buffers  är ett strukturerat dataserialiseringsprotokoll ( överföring ) som föreslagits av Google som ett effektivt binärt alternativ till XML -textformatet . Utvecklarna rapporterar att Protocol Buffers är enklare, mindre och snabbare än XML , eftersom de överför binär data optimerad för den minsta meddelandestorleken [2] .

Allmän information

Som utvecklarna tänkt på måste datastrukturen först beskrivas, som sedan sammanställs i klasser. Tillsammans med klasserna kommer kod för att serialisera dem i ett kompakt representationsformat. Läsa och skriva data är tillgängligt på högnivåprogrammeringsspråk som Java , C++ eller Python .

2010 bytte Twitter -backend till Protocol Buffers. Enligt utvecklarna av Twitter skulle en databas med en biljon tweets i XML ta upp tio petabyte istället för en. [3]

Enligt Google , Protocol Buffers vs. XML : [2]

Protokollbuffertar är inte avsedda att läsas av användaren och är i binärt format. För att deserialisera data behöver du en separat .proto -fil som definierar meddelandeformatet.

Protokollformat

I allmänhet är formatet en kodad sekvens av fält som består av en nyckel och ett värde. Nyckeln är numret som definieras för varje meddelandefält i protofilen. Varje fält föregås av ett gemensamt kodat variantfältnummer och fälttyp. Om typen är en sträng ( string), ett bifogat meddelande, ett upprepande meddelande eller en uppsättning byte ( bytes), följer storleken på data i varintformat. Därefter kommer värdet som motsvarar fältet (data) [4] .

Ett tal i varintformat ( int32och int64) kodas till en sekvens av byte där alla utom de sista byte har den mest signifikanta biten ( MSB ) satt till 1. När den konverteras till standardrepresentation kasseras den mest signifikanta biten av varje byte, och de återstående 7-bitars komponenterna är anslutna till varandra, den andra i omvänd ordning [4] . Åttabitars varintformatet valdes för att minska paketstorleken vid sändning av små nummer. Så om talet är mindre än 128 tar det bara 1 byte. Siffror nära det maximala möjliga tar dock upp mer plats än i det vanliga formatet. Till exempel är det maximala värdet som kan lagras i 8 byte i varintformat 10 byte. Negativa tal i varintformat har alltid den största storleken, beroende på typ, eftersom den mest signifikanta biten av det signerade numret är satt till 1.

Problemet med att koda negativa tal löstes med hjälp av ZigZag ( sint32och sint64) algoritmen, vars essens är att överföra teckenbiten från den höga ordningen till den låga. ZigZag-kodning förutsätter att positiva och negativa tal kommer att alternera med varandra när det kodade värdet ökar. I det här fallet kommer jämna tal att vara positiva och udda tal kommer att vara negativa.

Låt value - det ursprungliga värdet, och N - bitdjupet för datatypen för det ursprungliga värdet, och encoded_value - värdet som kodas av ZigZag-algoritmen, då kan kodningen skrivas med uttrycket i C-språket :

kodat_värde = ( värde << 1 ) ^ ( värde >> ( N - 1 ));

Det bör noteras att den andra skiftoperationen är ett aritmetiskt skift, det vill säga när ett negativt tal skiftas åt höger, fylls de höga bitarna med ettor, inte nollor (teckenbitskift).

Avkodning görs på ett mer komplicerat sätt: XOR att skifta det kodade värdet med 1 åt höger för att ta bort teckenbiten, och teckenbiten som erhålls från det kodade numret, projiceras på alla bitar genom att multiplicera med maxvärdet för Nbitar. Således överförs teckenbiten från den minst signifikanta biten till den mest signifikanta:

uvalue = (( kodat_värde & 1 ) * MAX_VALUE ( N )) ^ ( kodat_värde >> 1 );

Värdet MAX_VALUE(N)motsvarar värdet med Nsiffrorna fyllda med ettor (till exempel 0xffffffffvid N=32). Att multiplicera den minst signifikanta biten som satts till 1 med detta tal kommer att motsvara värdet −1 i den signerade datatypen. I C måste avkodning göras för värden encoded_valueoch uvalueen osignerad typ, och sedan måste värdet uvaluekonverteras till en signerad typ utan att ändra bitrepresentationen.

Alla numeriska värden, förutom fixed64, sfixed64och double, är kodade i protokollet i varintformatet.

Användningsexempel

För att definiera strukturen för den serialiserade datan är det nödvändigt att skapa en .proto -fil med källkoden för denna struktur. Nedan finns ett exempel på en .proto -fil för version 2 av Protocol Buffers, som beskriver information om bilen: märke, karosstyp, färg, tillverkningsår och information om tidigare ägare.

meddelande Bil { obligatorisk strängmodell = 1 ; _ enum BodyType { sedan = 0 ; halvkombi = 1 ; SUV = 2 ; } obligatorisk BodyType- typ = 2 [ standard = sedan ]; valfri strängfärg = 3 ; _ krävs int32 år = 4 ; meddelande Ägare { obligatoriskt strängnamn = 1 ; _ obligatorisk sträng efternamn = 2 ; krävs int64 förarlicens = 3 ; } upprepad Ägare föregående Ägare = 5 ; }

Efter att filen med önskad datastruktur har skapats måste du kompilera den med en kompilator för ditt programmeringsspråk för att generera en klass för åtkomst till dessa data. Den här klassen kommer att innehålla de enklaste åtkomstmetoderna för alla get/set-typfält, såväl som metoder för att serialisera och deserialisera din datastruktur till/från en byte-array.

Det är anmärkningsvärt att du kan lägga till nya fält till en redan skapad datastruktur utan att förlora kompatibiliteten med den tidigare versionen: när du analyserar gamla poster kommer nya fält helt enkelt att ignoreras.

Implementering

För tillfället har Google skapat kompilatorer för programmeringsspråk: C++ , Java , Python , Go , C# , Objective C , JavaScript [5] . Men det finns ett antal tredjepartsprojekt som har skapat kompilatorer för följande programmeringsspråk: 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 för C-språk

För att använda protokollet i C -språket utan tredjepartsbibliotek måste du antingen använda inlägg i C++-språket, om sådana stöds av den använda kompilatorn, eller linda in koden som genereras för C++ i form av bibliotek. Om sådana alternativ inte är lämpliga är följande kodgeneratorer kända:

  • protobuf-c (inget stöd för minnesallokeringsfel, men du kan använda dina egna minnesallokeringsmekanismer);
  • nanopb (optimerad för låg minnesförbrukning);
  • protobuf-embedded-c (arkiverat projekt).

Alternativa protokoll

Det mest högpresterande alternativet är FlatBuffers- biblioteket., som låter dig komma åt serialiserade data utan att kopiera dem i delar till separata minnesområden. Följaktligen överförs data i samma form som den används, och därför ökar mängden överförd data.

Apache Avro- projektskiljer sig genom att det inte kräver kodgenerering när man ändrar dataschemat när det används i dynamiskt skrivna språk, och själva schemat beskrivs i JSON-format .

Jämförelse med Apache Thrift

Nyckelfunktionerna i Apache Thrift är förmågan att skicka associativa arrayer, listor och uppsättningar, samt inbyggt stöd för fjärranrop för procedur [7] .

Protokollbuffertar Apache sparsamhet
Utvecklaren Google Facebook, Apache
Språk som stöds C++, Dart, Go, Java, Python, Ruby, C#, Objective C, JavaScript och PHP [8] C++, Java, JavaScript, Python, PHP, XSD, Ruby, C#, Perl, Objective C, Erlang, Smalltalk, OCaml och Haskell
Utgående format Binär Binär, JSON
Enkla typer bool, 32/64-bitars heltal, float, dubbel, sträng, bytesekvens. Upprepade egenskaper fungerar som listor. bool, byte, 16/32/64-bitars heltal, dubbel, sträng, bytesekvens, map<t1,t2>, lista<t>, set<t>.
Konstanter Inte Ja
Komposittyp Meddelande Strukturera
Undantag Inte Ja
Dokumentation Bra mager
Licens BSD stil Apache
Förlängningar av komposittyp Ja Inte

Anteckningar

  1. Release 21.8 - 2022.
  2. 1 2 Developer Guide - Protocol Buffers Arkiverad 11 september 2014 på Wayback Machine // Google Developers, 2 april 2012.
  3. Twitter löser sin dataformateringsutmaning - Computerworld . Tillträdesdatum: 6 januari 2011. Arkiverad från originalet den 17 oktober 2010.
  4. ↑ 12 Kodning | Protokollbuffertar | Google Developers  (engelska) . Googles utvecklare. Hämtad 11 oktober 2017. Arkiverad från originalet 5 september 2017.
  5. API-referens - Protokollbuffertar - Google-kod . Hämtad 22 maj 2017. Arkiverad från originalet 15 juli 2017.
  6. Tredjepartstillägg för protokollbuffertar
  7. Thrift vs Protocol Bufffers vs JSON Arkiverad 7 november 2015 på Wayback Machine , MirthLab LLC, 2009
  8. API-referens | Protokollbuffertar  . _ Googles utvecklare. Hämtad 4 mars 2019. Arkiverad från originalet 10 april 2019.

Länkar