概述
Apache Thrift和Protocol Buffers(protobuf)是兩種功能類似的二進位制編碼協議。Protocol Buffers最初由Google開發,而Thrift則由Facebook開發。它們都在2007-08年進行了開源。
Protobuf和Thrift都需要事先定義好schema。對於Thrift,它的schema用Thrift IDL(Interface definition language)來描述,例如:
struct Person { 1: required string userName, 2: optional i64 favoriteNumber, 3: optional list
相同的schema在Protobuf中的定義很像:
message Person { required string user_name = 1; optional int64 favorite_number = 2; repeated string interests = 3;}
Thrift和Protobuf都有各自的程式碼生成工具,用來生成給定schema在不同語言中的類程式碼。應用程式可以透過這些自動生成的程式碼對資料進行編碼或者解碼。
二進位制編碼格式
Thrift有兩種不同的二進位制編碼格式,分別叫做BinaryProtocol和CompactProtocol。先來看BinaryProtocol,我們以這樣一段資料為例:
{ “userName”: “Martin”, “favoriteNumber”: 1337, “interests”: [“daydreaming”, “hacking”]}
它在編碼後的資料格式如下所示:
在這種格式中,每一個欄位都會有其對應的型別和欄位的長度。字串以ASCII編碼儲存在data中。
值得注意的是,在這種格式中沒有儲存欄位的名字。每一個欄位都用一個整數來標識。這些整數標識在schema中被指定。
另一種格式CompactProtocol在語法上與BinaryProtocol是等價的。具體格式如下:
與BinaryProtocol的例子相比,相同內容的CompactProtoco版本僅佔用34個位元組。其原因在於它把欄位型別與欄位標識合併到一個位元組裡。並且透過使用可變長整數,從而實現用兩個位元組來儲存原本需要8個位元組的1337。其中,每一個位元組的最高位用來標識是否還需要更多的位元組。
最後一個例子,Protobuf的位元組格式跟Thrift CompactProtocol非常相似,只需要33個位元組
需要注意的是,schema中每個欄位是required或者是optional的資訊並不儲存在二進位制編碼中,而是在runtime時進行檢查。
(End)