Protocol Buffers 與 JSON 之間的選擇指南
1. 概述
Protocol Buffers (Protobuf) 和JSON是流行的資料序列化格式,但在可讀性、效能、效率和大小方面存在顯著差異。
在本教程中,我們將比較這些格式並探討它們的權衡。當我們需要選擇其中一個時,這將幫助我們根據用例做出明智的決定。
2. 可讀性和架構要求
Protobuf 需要預先定義的模式來定義資料的結構。這是一個嚴格的要求,沒有它我們的應用程式就無法解釋二進位資料。
為了更好地理解,讓我們來看一個範例schema.proto檔案:
syntax = "proto3";
message User {
string name = 1;
int32 age = 2;
string email = 3;
}
message UserList {
repeated User users = 1;
}
此外,如果我們看到 Base64 編碼的 Protobuf 訊息範例,它缺乏人類可讀性:
ChwKBUFsaWNlEB4aEWFsaWNlQGV4YW1wbGUuY29tChgKA0JvYhAZGg9ib2JAZXhhbXBsZS5jb20=
我們的應用程式只能結合架構文件來解釋這些數據。
另一方面,如果我們要以 JSON 格式表示相同的數據,我們可以不依賴任何嚴格的模式來做到這一點:
{
"users": [
{
"name": "Alice",
"age": 30,
"email": "[email protected]"
},
{
"name": "Bob",
"age": 25,
"email": "[email protected]"
}
]
}
此外,編碼資料是完全人類可讀的。
但是,如果我們的專案需要對 JSON 資料進行嚴格的驗證,我們可以使用JSON Schema ,這是一個用於定義和驗證 JSON 資料結構的強大工具。雖然它提供了顯著的好處,但它的使用是可選的。
3. 模式演化
Protobuf 強制執行嚴格的架構,確保強大的資料完整性,而 JSON 可以促進讀取時架構的資料處理。讓我們了解這兩種資料格式如何以不同的方式支援底層資料模式的演變。
3.1.消費者解析的向後相容性
向後相容性意味著新程式碼仍然可以讀取舊程式碼寫入的資料。因此,它要求新版本正確地反序列化使用舊模式版本序列化的資料。
為了確保與 JSON 的向後相容性,應用程式應設計為在反序列化期間忽略無法識別的欄位。此外,消費者應該為任何未設定的欄位提供預設值。使用 Protocol Buffers,我們可以直接在模式本身中新增預設值,從而增強相容性並簡化資料處理。
此外,Protobuf 的任何架構變更都必須遵循最佳實務以保持向後相容性。如果我們要新增字段,則必須使用以前未使用過的唯一字段編號。同樣,我們需要棄用未使用的欄位並保留它們,以防止重複使用可能破壞向後相容性的欄位編號。
儘管我們可以在使用這兩種格式時保持向後相容性,但協定緩衝區的機制更加正式和嚴格。
3.2.消費者解析的前向相容性
向前相容性意味著舊程式碼可以讀取新程式碼寫入的資料。它要求舊版本正確反序列化由新模式版本序列化的資料。
由於舊程式碼無法預測可能發生的資料語義的所有潛在更改,因此保持前向相容性更加困難。為了向前相容,舊程式碼必須忽略未知屬性並依賴新模式來保留原始資料語義。
對於 JSON,應用程式應設計為明確忽略未知字段,這對於大多數 JSON 解析器來說很容易實現。相反,Protocol Buffers 具有忽略未知欄位的內建功能。因此,protobuf 可以在保證未知欄位被忽略的情況下不斷發展。
最後,需要注意的是,刪除強製字段會破壞這兩種情況下的前向相容性。因此,建議的做法是棄用這些欄位並逐漸刪除它們。對於 JSON,常見的做法是棄用文件中的欄位並與消費者溝通。另一方面,Protocol Buffers 允許使用更正式的機制來棄用模式定義中的欄位。
4. 序列化、反序列化與效能
JSON 序列化涉及將物件轉換為基於文字的格式。另一方面,Protobuf 序列化將物件轉換為緊湊的二進位格式,同時符合.proto模式檔案的定義。
由於 Protobuf 可以引用架構來識別欄位名稱,因此在序列化時不需要將它們與資料一起保留。因此,Protobuf 格式比 JSON 更節省空間,後者保留了欄位名稱。
按照設計,Protobuf 在效率和性能方面通常優於 JSON。它通常佔用更少的儲存空間,並且通常比 JSON 資料格式更快地完成序列化和反序列化過程。
5. 何時使用 JSON
JSON 是 Web API(尤其是 RESTful 服務)事實上的標準。這主要歸功於其豐富的工具、函式庫生態系統以及與 JavaScript 的固有相容性。
而且,基於文字的性質使得調試和編輯變得容易。因此,使用 JSON 作為配置資料是一個自然的選擇,因為配置應該易於人類理解和編輯。
另一個有趣的用例是日誌記錄,首選使用 JSON 格式。由於其無模式的性質,它提供了極大的靈活性,可以將來自不同應用程式的日誌收集到集中位置,而無需維護嚴格的模式。
最後,需要注意的是,使用 Protobuf 時,需要特殊的模式感知客戶端和其他工具,而對於 JSON,則不需要特殊的客戶端,因為 JSON 是純文字格式。因此,在開發原型或 MVP 解決方案時,我們可能會從 JSON 格式中受益,因為它允許我們以更少的努力引入更改。
6. 何時使用 Protocol Buffer
協定緩衝區對於透過網路進行儲存和傳輸非常有效。此外,他們還透過模式定義強制執行嚴格的資料完整性規則。因此,對於此類用例,我們可能會從它們中受益。
處理即時分析、遊戲和金融系統的應用程式預計將具有超強的效能。因此,我們必須評估在這種場景下使用Protobuf的可能性,特別是對於內部溝通。
此外,分散式資料庫系統可以受益於 Protobuf 較小的記憶體佔用。因此, Protocol Buffers 是編碼資料和元資料以實現高效能資料儲存和高效能資料存取的絕佳選擇。
七、結論
在本文中,我們探討了 JSON 和 Protocol Buffers 資料格式之間的主要區別,以便在為我們的應用程式製定資料編碼策略時能夠做出明智的決策。
JSON 的人類可讀性和靈活性使其成為 Web API、設定檔和日誌記錄等用例的理想選擇。相較之下,協定緩衝區提供卓越的效能和效率,使其適合即時分析、遊戲和分散式儲存系統。