2015-01-15 77 views
0

我知道protobuf/thrift需要獨特的數字字段標籤來提供版本兼容性。它們提供版本兼容性通過序列化消息(種)以這種方式:字段標記是否可以從protobuf/thrift消息中刪除?

<tag1> <value1> ... <tagN> <valueN>

反序列化時,他們拿起標籤值,查找消息模式,並知道要填寫值存入哪個字段。這樣,只要我們添加具有不同標籤值的新字段,這些消息將是兼容的。

但我不認爲這是一個很好的設計:

  1. 標籤值必須在消息中編碼。這有一些開銷。

    例如。當客戶多次調用遠程服務器上的RPC方法時,每個請求/響應中的標記值都是相同的。一次只發送<tag1> <value1> ... <tagN> <valueN>然後只發送<value1> ... <valueN>會很好。

  2. 當更改字段的類型時,我們還需要更改標記值。忘記這麼做會導致錯誤。

  3. 開發人員必須確保標籤值是唯一的。通常人們追蹤上次使用的標籤ID並在添加新字段時增加它。但是,當兩個人在不同分支中添加字段並進行合併時,很難解決衝突。

我想一個更好的設計可能是:

爲每個消息類型的緊湊型模式,如:

<field_name_1> <field_type_1> ... <field_name_N> <field_type_N>(根據FIELD_NAME排序)

爲了解決問題1 ,在做任何事之前交換消息模式。對於RPC示例,客戶端將在發送第一個RPC之前發送其消息模式,然後在以下RPC中僅發送<value_1> ... <value_N>。服務器在請求到達時將具有消息模式,並知道如何反序列化它。

爲了解決問題2,當字段類型改變時,緊湊型消息模式也將被改變。程序將能夠發現新舊架構不匹配,並報告錯誤。

要解決問題3,開發人員不再需要處理分配唯一標記值的問題。他們仍然需要分配唯一的字段名稱,但這應該更容易,並且導致合併衝突的可能性更小。

這可能是一個可用的設計?它會有什麼問題?

+0

我想知道如果任何人有關於上面提到的這個問題建議: 「3.Developers必須確保標籤值是唯一通常人們追蹤最近使用的標籤ID和增加新的領域時增加,但是當。兩個人在不同的分支添加字段併合並,難以解決衝突。「 我在想這些數字可能會以某種方式與分支相關聯。 或者也許更好的索引中央存儲庫 – tdugan

回答

2

我相信Apache Avro的工作方式就像你描述的那樣,所以也許你應該嘗試一下。

但是,我會爭辯說,前期的模式協商向協議添加了大量的複雜功能,超過了任何好處。在簡單情況下看起來似乎很容易,但是在一個大型系統中,您有代理(不知道他們在代理什麼),專用存儲服務器,從多個發件人收到的具有不同協議版本的消息組成的消息等等,跟蹤模​​式版本的複雜性成爲一個巨大的負擔。

+0

哦,這是一個很好的觀點! –

相關問題