Protokollbuffertar | |
---|---|
Sorts | dataserialiseringsformat |
Utvecklaren | |
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] .
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.
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.
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.
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] .
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:
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 .
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 | 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 |