Upload
yuichi-ito
View
4.540
Download
1
Embed Size (px)
Citation preview
Protocol Buffers 入門伊藤 裕一 (Yuichi110)
Agenda
• 分散システムと Protocol Buffers
• Protocol Buffers の簡単な使い方
• Json などの従来技術との比較
• Protocol Buffers で RPC を実現する
• Q & A
2
自己紹介
• 伊藤裕一 (twitter: yuichi110)
• - 2016 : Cisco データセンタースイッチ (ネットワーク屋)
• 2016 - : Nutanix ハイパーコンバージド�(サーバー屋)
• 趣味でコード書いたり。。。
3
最近 MyNavi での連載が終了 全36回(2015/05/25 - 2016/02/04)
4
Protocol Buffers from Google
Protocol buffers are a language-neutral, platform-neutral extensible mechanism for serializing structured data.
分散システム
• 複数の「ノード」が連携してシステムとなる
• ノードがダウンしても他のノードが処理を継続
5
Node Node Node Node
DistributedSystem
Switch Switch
有名な分散システム
• SaaS (Google のサービス系)
• スパコンの対極
6
Cheap Server Cluster
ノード間の連携
• クラスタのノード間の通信は TCP/IP ネットワーク経由
• パケットのペイロードにシステムの情報をのせる
7
Node A Node B
Packet
Packet
mac | ip | tcp | payload (data)今日はここの話 !!
Protocol Buffers�で何ができる ? (1)
• データをシリアライズ化するフォーマット
• 入力データをシリアライズ化して圧縮
• 圧縮されたデータをデシリアライズ(解凍)化して戻す
8
structured data serialized data
serialized data structured data
SerializerProtocol Buffers
De-SerializerProtocol Buffers
Protocol Buffers�で何ができる ? (2)
• RPC (Remote Procedure Call) のフレームワーク
• 内部的にシリアライズ・デシリアライズを利用
9
Node AClient
Node BServer
RPC を定義: add(int x, int y) -> int z
call : add(1,2)
return : 3 calc : 1 + 2 -> 3
Agenda
• 分散システムと Protocol Buffers
• Protocol Buffers の簡単な使い方
• Json などの従来技術との比較
• Protocol Buffers で RPC を実現する
• Q & A
10
Protocol Buffer を利用する流れ
• プロトコルを定義したファイルを作成
• ファイルをコンパイルしてコードを生成
• そのコードを使ってシリアライズ/デシリアライズ/RPC
11
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++
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
message Person { required string name = 1; required int32 id = 2; optional string email = 3;
repeated PhoneNumber phone = 4;}
Languagemessage has numbered fields
each field has a name and a value type
Field NumberField NameField Value Type
numbers (integer or floating-point), booleans, strings, raw bytes, etc
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
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
Language
• その他多数の機能
• import
• extend
• service (後述)
• map etc
• 詳細は Language Guide にて
17
.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 (コード)
.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
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 darwinType "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
>>> person = addressbook_pb2.Person() >>> person.id = 1234 >>> person.name = "Jon Doe" >>> person.email = “[email protected]" >>> person.SerializeToString() '\n\x07Jon Doe\x10\xd2\t\x1a\[email protected]’
シリアライズ
>>> person2 = addressbook_pb2.Person() >>> person2.ParseFromString("\n\x07Jon Doe\x10\xd2\t\x1a\[email protected]") >>> person2.name u'Jon Doe'
デシリアライズpayload にのせてやりとり
Agenda
• 分散システムと Protocol Buffers
• Protocol Buffers の簡単な使い方
• Json などの従来技術との比較
• Protocol Buffers で RPC を実現する
• Q & A
22
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
XML/JSON を使ったデータの受け渡し
24
Node A Node BPacket
XML/JSON writer
Structured Data
XML/JSON parser
Structured Data
Object Object
socket, REST etc
ユーザがオブジェクトとXML/JSONのマッピング
Protocol buffers を使ったデータの受け渡し
Node A Node BPacket
serialize(protobuf)
Structured Data(protobuf)
de-serialize(protobuf)
Structured Data(protobuf)
Binary
Object Object
Binary
socket, REST etc
クラスの利用でオブジェクトのマッピングが不要
Protobuf が JSON/XML に勝る点
• reader/writer の処理を自分で書かなくて良い
• 読み書きの処理速度に優れる
• コード変更時のバグが少ない
• データ量が減るため通信が高速化
• 第三者への難読化
26
Protobuf が JSON/XML に劣る点
• protocol buffers のインストールが必要
• ブラウザなどを通した「外部」からの利用には向いていない
• サービスの「内部」での利用がメイン
• 小さいデータのやりとりには手間がかかりすぎる
27
Protobuf が JSON/XML と共通
• データをどう表現するかという「フォーマット」
• REST などの「コミュニケーション手段」とは別
28
Agenda
• 分散システムと Protocol Buffers
• Protocol Buffers の簡単な使い方
• Json などの従来技術との比較
• Protocol Buffers で RPC を実現する
• Q & A
29
Nutanix での実利用例
30
仮想化に SAN, ストレージが不要
Nutanix での実利用例
31
Host A Host B Host C
VM1 VM2 VM3 VM4 VM5 VM6
Storage (Hyper Converged)
Nutanix Cluster
Browser
power off vm 6
PrismWeb Server
Browser click power off button on vm 6
PrismWeb Server
PrismWeb Server
AcropolisVM Management
AcropolisVM Management
AcropolisVM Management
AHVHyperVisor
AHVHyperVisor
AHVHyperVisor
Node A Node B Node C
Controller
Host
Master
run the VM6Protobuf
rest
Nutanix での実利用例
33
…
機能 A
汎用 proto
機能 B
make class
class
class…
egg file
合体
Nutanix での実利用例
34
Order 1
Order 2
Order 3
Gen
eral
RPC
Util
ity (p
roto
buf)
rest + protobuf
From
Order 1
Order 2
Order 3Py
thon
web
ser
ver
To
Oth
er C
ompo
nent
sTh
e C
ompo
nent
Prot
obuf
Ser
v
Acropolis Acropolis
Nutanix での実利用例
RPC の実現 (1)
• .proto file に RPC を定義
• RPC名(services)、引数(message)、返り値(message)
• クライアント : 生成された RPC の呼び出し
• サーバー : 届けられたデータをデシリアライズし返り値を返す
35
message searchRequest {} message searchResponse {}
service searchService { rpc Search (ServiceRequest) returns (SearchResponse); }
search.proto
Node A Node B
message A
call RPC
Structured Data(message A)
de-serializeBinary
Object Object
Binary
Structured Data(message A)
messageB
get RPC result
Structured Data(message B)
Binary
Structured Data(message B)
Binary
serializeObject
implementation
Object
Node A Node B
request
call RPC
Structured Data(message A)
de-serializeBinary
Object Object
Binary
Structured Data(message A)
response
get RPC result
Structured Data(message B)
Binary
Structured Data(message B)
Binary
serializeObject
implementation
Object
service
RPCのためのクラス
• RpcController : 継承して細かい挙動の定義
• RpcChannel : 継承して RPC 通信の方法を実装
• Service�Class : .proto file から生成されて上記を利用
38
1. Controller, Channel を用意 2. Serviceクラスをインスタンス化 3. 上記インスタンスにRPC引数等を渡す 4. RPCの結果はコールバック等で受け取る
言語により若干の違いあり 詳細は公式ドキュメント等にて
Agenda
• 分散システムと Protocol Buffers
• Protocol Buffers の簡単な使い方
• Json などの従来技術との比較
• Protocol Buffers で RPC を実現する
• Q & A
39
Thank you !!