Protocol Buffers 入門

4,701 views

Published on

protocol buffers の簡単な説明です。

Published in: Software

Protocol Buffers 入門

  1. 1. Protocol Buffers 入門 伊藤 裕一 (Yuichi110)
  2. 2. Agenda • 分散システムと Protocol Buffers • Protocol Buffers の簡単な使い方 • Json などの従来技術との比較 • Protocol Buffers で RPC を実現する • Q & A 2
  3. 3. 自己紹介 • 伊藤裕一 (twitter: yuichi110) • - 2016 : Cisco データセンタースイッチ (ネットワーク屋) • 2016 - : Nutanix ハイパーコンバージド�(サーバー屋) • 趣味でコード書いたり。。。 3 最近 MyNavi での連載が終了 全36回(2015/05/25 - 2016/02/04)
  4. 4. 4 Protocol Buffers from Google Protocol buffers are a language-neutral, platform-neutral extensible mechanism for serializing structured data.
  5. 5. 分散システム • 複数の「ノード」が連携してシステムとなる • ノードがダウンしても他のノードが処理を継続 5 Node Node Node Node Distributed System Switch Switch
  6. 6. 有名な分散システム • SaaS (Google のサービス系) • スパコンの対極 6 Cheap Server Cluster
  7. 7. ノード間の連携 • クラスタのノード間の通信は TCP/IP ネットワーク経由 • パケットのペイロードにシステムの情報をのせる 7 Node A Node B Packet Packet mac | ip | tcp | payload (data) 今日はここの話 !!
  8. 8. Protocol Buffers�で何ができる ? (1) • データをシリアライズ化するフォーマット • 入力データをシリアライズ化して圧縮 • 圧縮されたデータをデシリアライズ(解凍)化して戻す 8 structured data serialized data serialized data structured data Serializer Protocol Buffers De-Serializer Protocol Buffers
  9. 9. Protocol Buffers�で何ができる ? (2) • RPC (Remote Procedure Call) のフレームワーク • 内部的にシリアライズ・デシリアライズを利用 9 Node A Client Node B Server RPC を定義: add(int x, int y) -> int z call : add(1,2) return : 3 calc : 1 + 2 -> 3
  10. 10. Agenda • 分散システムと Protocol Buffers • Protocol Buffers の簡単な使い方 • Json などの従来技術との比較 • Protocol Buffers で RPC を実現する • Q & A 10
  11. 11. Protocol Buffer を利用する流れ • プロトコルを定義したファイルを作成 • ファイルをコンパイルしてコードを生成 • そのコードを使ってシリアライズ/デシリアライズ/RPC 11
  12. 12. message Person { required string name = 1; required int32 id = 2; optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME]; } repeated PhoneNumber phone = 4; } Language Language structure is similar to Java or C++
  13. 13. message Person { required string name = 1; required int32 id = 2; optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME]; } repeated PhoneNumber phone = 4; } Language message is a small logical record of information
  14. 14. message Person { required string name = 1; required int32 id = 2; optional string email = 3; repeated PhoneNumber phone = 4; } Language message has numbered fields each field has a name and a value type Field Number Field Name Field Value Type numbers (integer or floating-point), booleans, strings, raw bytes, etc
  15. 15. message Person { required string name = 1; required int32 id = 2; optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME]; } repeated PhoneNumber phone = 4; } Language can use other protocol buffer message as value type
  16. 16. message Person { required string name = 1; required int32 id = 2; optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME]; } repeated PhoneNumber phone = 4; } Language field type : required, optional, repeated
  17. 17. Language • その他多数の機能 • import • extend • service (後述) • map etc • 詳細は Language Guide にて 17
  18. 18. .proto file のコンパイル protoc -I=$SRC_DIR --python_out=$DST_DIR $SRC_DIR/FILE_NAME package tutorial; message Person { required string name = 1; required int32 id = 2; optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME]; } repeated PhoneNumber phone = 4; } message AddressBook { repeated Person person = 1; } addressbook.proto (定義) protoc --python_out=./ ./addressbook.proto コンパイル addressbook_pb2.py (コード)
  19. 19. .proto file のコンパイル • protoc のオプションで言語を選択 protoc --proto_path=IMPORT_PATH --cpp_out=DST_DIR path/to/file.proto --java_out=DST_DIR --python_out=DST_DIR 他の言語もコンパイラが存在している
  20. 20. 生成コードをロードしてみる 20 Python 2.7.10 (default, Oct 23 2015, 19:19:21) [GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import addressbook_pb2 >>> dir(addressbook_pb2) ['AddressBook', 'DESCRIPTOR', 'Person', '_ADDRESSBOOK', '_PERSON', '_PERSON_PHONENUMBER', '_PERSON_PHONETYPE', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_b', '_descriptor', '_message', '_reflection', '_sym_db', '_symbol_database', 'descriptor_pb2', 'sys'] >>> dir(addressbook_pb2.Person) ['ByteSize', 'Clear', 'ClearExtension', 'ClearField', 'CopyFrom', 'DESCRIPTOR', 'EMAIL_FIELD_NUMBER', 'FindInitializationErrors', 'FromString', 'HOME', 'HasExtension', 'HasField', 'ID_FIELD_NUMBER', 'IsInitialized', 'ListFields', 'MOBILE', 'MergeFrom', 'MergeFromString', 'NAME_FIELD_NUMBER', 'PHONE_FIELD_NUMBER', 'ParseFromString', 'PhoneNumber', ‘PhoneType', … ’_decoders_by_tag’, '_extensions_by_name', '_extensions_by_number', '_fields', '_is_present_in_parent', '_listener', '_listener_for_children', '_oneofs', '_unknown_fields', 'email', 'id', 'name', 'phone'] addressbook.proto をコンパイル ファイル名がパッケージに message がクラスに フィールドが変数に
  21. 21. コードでデータをシリアライズ/デシリアライズ 21 >>> person = addressbook_pb2.Person() >>> person.id = 1234 >>> person.name = "Jon Doe" >>> person.email = “jdoe@example.com" >>> person.SerializeToString() 'nx07Jon Doex10xd2tx1ax10jdoe@example.com’ シリアライズ >>> person2 = addressbook_pb2.Person() >>> person2.ParseFromString("nx07Jon Doex10xd2tx1ax10jdoe@example.com") >>> person2.name u'Jon Doe' デシリアライズ payload にのせてやりとり
  22. 22. Agenda • 分散システムと Protocol Buffers • Protocol Buffers の簡単な使い方 • Json などの従来技術との比較 • Protocol Buffers で RPC を実現する • Q & A 22
  23. 23. XML/JSON の復習 23 <employees> <employee> <firstName>John</firstName> <lastName>Doe</lastName> </employee> <employee> <firstName>Anna</firstName> <lastName>Smith</lastName> </employee> <employee> <firstName>Peter</firstName> <lastName>Jones</lastName> </employee> </employees> XML Mark up {"employees":[ {"firstName":"John", "lastName":"Doe"}, {"firstName":"Anna", "lastName":"Smith"}, {"firstName":"Peter", "lastName":"Jones"} ]} JSON Key and Value
  24. 24. XML/JSON を使ったデータの受け渡し 24 Node A Node B Packet XML/JSON writer Structured Data XML/JSON parser Structured Data Object Object socket, REST etc ユーザがオブジェクトとXML/JSONのマッピング
  25. 25. Protocol buffers を使ったデータの受け渡し Node A Node B Packet serialize (protobuf) Structured Data (protobuf) de-serialize (protobuf) Structured Data (protobuf) Binary Object Object Binary socket, REST etc クラスの利用でオブジェクトのマッピングが不要
  26. 26. Protobuf が JSON/XML に勝る点 • reader/writer の処理を自分で書かなくて良い • 読み書きの処理速度に優れる • コード変更時のバグが少ない • データ量が減るため通信が高速化 • 第三者への難読化 26
  27. 27. Protobuf が JSON/XML に劣る点 • protocol buffers のインストールが必要 • ブラウザなどを通した「外部」からの利用には向いていない • サービスの「内部」での利用がメイン • 小さいデータのやりとりには手間がかかりすぎる 27
  28. 28. Protobuf が JSON/XML と共通 • データをどう表現するかという「フォーマット」 • REST などの「コミュニケーション手段」とは別 28
  29. 29. Agenda • 分散システムと Protocol Buffers • Protocol Buffers の簡単な使い方 • Json などの従来技術との比較 • Protocol Buffers で RPC を実現する • Q & A 29
  30. 30. Nutanix での実利用例 30 仮想化に SAN, ストレージが不要
  31. 31. Nutanix での実利用例 31 Host A Host B Host C VM1 VM2 VM3 VM4 VM5 VM6 Storage (Hyper Converged) Nutanix Cluster Browser power off vm 6
  32. 32. Prism Web Server Browser click power off button on vm 6 Prism Web Server Prism Web Server Acropolis VM Management Acropolis VM Management Acropolis VM Management AHV HyperVisor AHV HyperVisor AHV HyperVisor Node A Node B Node C Controller Host Master run the VM6Protobuf rest Nutanix での実利用例
  33. 33. 33 … 機能 A 汎用 proto 機能 B make class class class … egg file 合体 Nutanix での実利用例
  34. 34. 34 Order 1 Order 2 Order 3 GeneralRPCUtility(protobuf) rest + protobuf From Order 1 Order 2 Order 3 Pythonwebserver To OtherComponentsTheComponent ProtobufServ Acropolis Acropolis Nutanix での実利用例
  35. 35. RPC の実現 (1) • .proto file に RPC を定義 • RPC名(services)、引数(message)、返り値(message) • クライアント : 生成された RPC の呼び出し • サーバー : 届けられたデータをデシリアライズし返り値を返す 35 message searchRequest {} message searchResponse {} service searchService { rpc Search (ServiceRequest) returns (SearchResponse); } search.proto
  36. 36. Node A Node B message A call RPC Structured Data (message A) de-serialize Binary Object Object Binary Structured Data (message A) messageB get RPC result Structured Data (message B) Binary Structured Data (message B) Binary serialize Object implementation Object
  37. 37. Node A Node B request call RPC Structured Data (message A) de-serialize Binary Object Object Binary Structured Data (message A) response get RPC result Structured Data (message B) Binary Structured Data (message B) Binary serialize Object implementation Object service
  38. 38. RPCのためのクラス • RpcController : 継承して細かい挙動の定義 • RpcChannel : 継承して RPC 通信の方法を実装 • Service�Class : .proto file から生成されて上記を利用 38 1. Controller, Channel を用意 2. Serviceクラスをインスタンス化 3. 上記インスタンスにRPC引数等を渡す 4. RPCの結果はコールバック等で受け取る 言語により若干の違いあり 詳細は公式ドキュメント等にて
  39. 39. Agenda • 分散システムと Protocol Buffers • Protocol Buffers の簡単な使い方 • Json などの従来技術との比較 • Protocol Buffers で RPC を実現する • Q & A 39
  40. 40. Thank you !!

×