protobufシーケンス化プロトコルの紹介

4993 ワード

Protocol Bufferの概要
  • Google Protocol Buffer(略称Protobuf)はGoogle社内のハイブリッド言語データ標準であり、構造化データのシリアル化、またはシーケンス化に使用できる軽量で効率的な構造化データストレージフォーマットである.通信プロトコル、データストレージなどの分野で使用できる無関係言語、無関係プラットフォーム、拡張可能なシーケンス化構造データフォーマットである.
  • は、構造化されたデータをシリアル化(シーケンス化)することにより、データ記憶/RPCデータ交換の機能を実現する.
  • シーケンス化:データ構造またはオブジェクトをバイナリ列に変換するプロセス.
  • 逆シーケンス化:シーケンス化中に生成されたバイナリ列をデータ構造またはオブジェクトに変換するプロセス.


  • シーケンス化プロトコルは何を考慮する必要がありますか?
  • シーケンス化後のストリームサイズ(ネットワークブロードバンド占有)
  • シーケンス化と逆シーケンス化の性能(CPU+メモリ等のリソース占有)
  • 言語間
  • をサポートするかどうか
    protobufの特徴
  • 性能面
  • は体積が小さい.シーケンス化後、データサイズはいずれも約3倍縮小した.
  • シーケンス化速度が速く、XMLとJsonより2~50倍速い.
  • は伝送速度が速い.体積が小さいため、伝送帯域幅と速度が最適化される.

  • 使用態様
  • 単純な使用、protobufコンパイラ自動シーケンス化および逆シーケンス化
  • はメンテナンスコストが低く、マルチプラットフォームはオブジェクトプロトコルファイルを1つだけ維持する必要があります.
  • は後方互換性がよく、拡張性がよく、データフォーマットを破壊する必要がなく、直接データフォーマットを更新することができる.
  • は暗号化性がよく、HTTP伝送パケットはシーケンス後のバイナリ列しか捕まえられない.

  • 使用範囲
  • クロスプラットフォーム
  • 言語間
  • 高拡張性

  • protobufの欠点
  • は、テキストがデータ構造を記述するのに適していないため、テキストベースのタグドキュメント(HTMLなど)のモデリングには適していない.
  • は汎用性が悪く、protobufはGoogle社内で使用されているツールにすぎず、大衆化されていない.
  • は、データ構造を理解するにはprotoファイルを使用する必要があるバイナリ・データ・ストリーム方式で格納される(読み取り不可).

  • フィールド・ルールの指定
  • require:フォーマットの良いmessageには、このフィールドが1回含まれる必要があります.
  • optional:フォーマットの良いmessageは、このフィールドを0回または1回含まなければならない.
  • repeated:このフィールドは、フォーマットの良いメッセージで任意の複数回(ゼロ回を含む)繰り返してもよく、繰り返しの順序は保持されます.(履歴上の理由により、スカラー数値タイプのrepeatedフィールドは可能な限り効率的に符号化できません.新しいコードは、より効率的な符号化を得るために特別なオプション[packed=true]を使用する必要があります.)
    repeated int32 samples = 4 [packed=true];
    
    //  :  required             。                  required   ,
                     -                  ,       
          。       buffers                   。      
            ,   required     ;         optional   repeated。  ,
            。
    

  • Reserved予約フィールド
  • メッセージタイプを完全に削除またはコメントで更新する場合は、将来のユーザーが更新または変更を行うときに、これらの番号を再び使用する可能性があります.同じ.protoの古いバージョンを後でロードすると、データ破損、プライバシーエラーなど、深刻な問題が発生する可能性があります.このようなことが起こらないことを確認する方法の1つは、削除されたフィールドのフィールド番号を指定することです(名前を予約ステータスと指定する必要がある場合もあります.英語名はJSONシーケンス化の問題を引き起こす可能性があります).将来のユーザーがこれらのフィールド識別子を使用しようとすると、protocol bufferコンパイラは文句を言います.
    message Foo {
    	reserved 2, 15, 9 to 11;
    	reserved "foo", "bar";
    }
    

  • インポート定義importing definitions
  • 別の.protoファイルのmessage定義を使用するには、ファイルの上部にimport文を追加することでファイルをインポートできます.
    import "myproject/other_protos.proto";
    
  • デフォルトでは、直接インポートを使用するしかありません.protoファイルの定義.しかし、時には必要になるかもしれません.protoファイルを新しい場所に移動します.これで、古い場所に仮想を配置できます.protoファイルは、import publicの概念を用いて、直接移動するのではなく、すべてのインポートを新しい場所に転送する.protoファイルは、1回の変更ですべての呼び出しポイントを更新します.import public文を含むprotoをインポートした誰でも、インポート共通の依存項目に依存を渡すことができます.
    // new.proto
    // All definitions are moved here
    
    
    // old.proto
    // This is the proto that all clients are importing.
    import public "new.proto";
    import "other.proto";
    
    
    // client.proto
    import "old.proto";
    //       old.proto   new.proto     ,      other.proto
    

  • メッセージタイプルールの更新
  • 既存のフィールドのフィールド番号を変更しないでください.
  • 新しく追加された任意のフィールドはoptionalまたはrepeatedフィールドであるべきである.
  • 更新メッセージタイプでフィールド番号を使用しない限り、必須でないフィールドを削除できます.
  • int 32,uint 32,int 64,uint 64,boolは互換性があります.これは、フィールドをこれらのタイプから別のタイプに変更することができ、前後の互換性を破壊することはありません.
  • sint 32およびsint 64は互いに互換性があるが、他の整数タイプとは互換性がない.
  • バイトが有効なUTF-8であればstringとbytesは互換性があります.
  • バイトがmessageの符号化バージョンを含む場合、埋め込みmessageはbytesと互換性がある.
  • fixed 32はsfixed 32と互換性があり、fixed 64はsfixed 64と互換性がある.
  • optionalはrepeatedと互換性がある.
  • デフォルト値を変更するのは通常正常です.ネットワークを通じてデフォルト値が送信されないことを覚えている限り.したがって、プログラムが特定のフィールドが設定されていないというメッセージを受信すると、プログラムのプロトコルバージョンで定義されたデフォルト値が表示されます.送信者コードで定義されたデフォルト値は表示されません.
  • enumはint 32,uint 32,int 64,uint 64と互換性があります(適切でない場合は値が遮断されることに注意してください).ただし、messageの逆シーケンス化ではクライアントコードが異なることに注意してください.メッセージが逆シーケンス化されると、認識できないenum値が破棄され、フィールドのhas...アクセサがfalseを返し、getterがenum定義にリストされている最初の値を返すか、デフォルト値を指定するとデフォルト値を返すことに注意してください.repeated列挙フィールドの場合、認識できない値はリストから削除されます.ただし、整数フィールドは常に値を保持します.したがって、範囲外の列挙値を受信する可能性がある場合、整数をenumにアップグレードする操作には注意が必要である.
  • 単一optional値をnewoneofに変更したメンバーは安全でバイナリ互換性があります.コードが一度に複数設定されていないと判断した場合は、複数のoptionalフィールドを新しいoneofに移動するのは安全かもしれません.しかし、任意のフィールドを既存のoneofに移動するのは安全ではありません.

  • protocol buffer messageタイプを定義する
    //         proto  
    /*
    *1.    :ID、  、  、  、  、    、    、    
    *2.    :  、PHP、  
    *3.    :ID、  、  
    */
    message BlogSystem{
    	enum TagType{
    		HOT = 1;
    		PHP = 2;
    		NEW = 3;
    	}
    	message AuthorMessage{
    		required int32 id = 1;
    		required string name = 2;
    		optional string introduce = 3; 
    	}
    	required int32 id = 1;
    	required string title = 2;
    	optional string description = 3;
    	required string content = 4;
    	required TagType tag = 5;
    	optional bool stick = 6;
    	required string createtime = 7;
    	required AuthorMessage author = 8;
    	
    }