blog

etcd を知る: etcd Core API v3

アルバムの概要\n\n\nproto3\netcd v3 の通信は gRPC に基づいています。 proto ファイルはサーバとクライアントの間のインタフェースを定義する標準です。すなわち、クライアン...

Apr 9, 2020 · 5 min. read
シェア

アルバムの概要

proto3

etcd v3の通信はgRPCをベースにしており、プロトファイルはサーバとクライアント間の通信インタフェースを定義する標準です。プロトファイルとは、サーバとクライアント間の通信インタフェース、つまり、クライアントからどのようなパラメータを渡すべきか、サーバからどのようなパラメータを返すべきか、クライアントから何を呼び出すべきか、ブロッキングかノンブロッキングか、同期か非同期かを定義する規格です。コアAPIの学習では、gRPCはproto3の使用を推奨し、proto3の基本的な構文の予備的な理解を持っている必要があります。proto3は、機能の削除された部分のアップグレード版の元のプロトコルバッファ2(proto2として知られている)、モバイルデバイスに最適化されたサポートは、アンドロイドとiOSのサポートを追加することに加えて、gRPCが正常に使用できるようにします。また、gRPCが問題なくモバイルデバイス上で使用できるように、アンドロイドとiOSのためのサポートを追加します。

Protocol Buffer

プロトコルバッファは、構造化データをシリアライズするための柔軟で効率的な自動メカニズムです。いったんデータの構造化方法を定義すれば、特別に生成されたソースコードを使用して、さまざまな言語で、さまざまなデータストリームで、構造化データを簡単に書いたり読んだりすることができます。レガシー」フォーマットでコンパイルされたプログラムを壊すことなく、定義されたデータ構造を更新することも可能です。

メッセージタイプの定義

まず、非常に単純な例を見てみましょう。検索リクエストメッセージを定義し、それぞれにクエリ文字列、興味のある特定のページ番号、各ページのヒット数を含める必要があるとします。

syntax = "proto3";
message SearchRequest {
 string query = 1;
 int32 page_number = 2;
 int32 result_per_page = 3;
}
  1. 検索要求メッセージ構造には、定義によって指定された3つのフィールドがあることを確認してください。各フィールドには名前と型があります。

フィールドタイプの指定

上記の例では、すべてのフィールドが値型です。しかし、フィールドには列挙型やその他のメッセージ・タイプなど、さまざまな型の組み合わせを指定することもできます。

識別子の割り当て - タグ

メッセージの各フィールドには一意な数値の識別子があります。これらの識別子は、メッセージのバイナリ・フォーマットでフィールドを識別するために使用され、一度メッセージが使用されると、これらの識別子は変更されるべきではありません。

識別番号は、識別番号とフィールドタイプを含めて1バイトで1から15までエンコードされることに注意してください。

識別子 16 から 2047 までは 2 バイト必要です。ですから、1 から 15 までは最も頻繁に出現するメッセージ・タイプのために確保 しておくべきです。つまり、1 から 15 を一度に使い切らずに、将来のために少し残しておくのです。

また、19000から19999までの数字は、プロトコルバッファで使用するために予約されているため、使用することができません。もし、自分の.protoファイルで予約された数字を使用すると、プロトコルバッファコンパイラからプロンプトが表示されます。自分の .proto ファイルで予約番号を使用すると、プロトコルバッファコンパイラがプロンプトを出します。同様に、予約された識別子を使用することはできません。

フィールドルールの指定

メッセージ・フィールドには以下のいずれかを指定します:

  1. singular:文法的に正しいメッセージには、これらのフィールドがゼロか1つ含まれています。
  2. repeated: フィールドは正規のメッセージの中で一定回数繰り返すことができます。繰り返される値の順序は保持されます。proto3では、繰り返し値型のフィールドはデフォルトで圧縮符号化されます。

メッセージタイプの追加

複数のメッセージタイプを一つの .proto ファイルで定義することができます。これは、複数の関連メッセージを定義する場合に便利です。例えば、検索メッセージ・タイプの応答メッセージ・フォーマットを定義したい場合、同じ.protoファイルに以下を追加することができます:

message SearchRequest {
 string query = 1;
 int32 page_number = 2;
 int32 result_per_page = 3;
}
message SearchResponse {
 ...
}

message SearchRequest {
 string query = 1;
 int32 page_number = 2; // Which page number do we want?
 int32 result_per_page = 3; // Number of results to return per page.
}

予約フィールド

message Foo {
 reserved 2, 15, 9 to 11;
 reserved "foo", "bar";
}

同じ予約文の中でフィールド名と識別子を混同しないように注意してください。

値の種類

この表は、.proto ファイルで使用できる型と、対応する言語用に自動生成される型を示したものです:

proto コンパイル方法

.proto ファイルがコンパイルされると、コンパイラは選択した言語用のコードを 生成します。フィールドの値の取得や設定、出力ストリームへのメッセージの直列化、入力ストリームからのメッセージの変換など、ファイルに記述するメッセージの種類を指定します。

  • C++ の場合、コンパイラは .proto ファイルごとに .h ファイルと .cc ファイルを 1 つずつ生成し、指定されたメッセージ・タイプごとに 1 つのクラスを生成します。
  • Java の場合、コンパイラは各メッセージ・タイプのクラスと、それらのメッ セージ・クラスのインスタンスを作成するための特別な Builder クラスを含む java ファイルを生成します。
  • Python コンパイラは、各メッセージタイプの静的記述子を生成するモジュールを生成し、このモジュールは実行時にメタクラスとともに使用され、必要な Python データアクセスクラスを作成します。
  • Goの場合、コンパイラーはメッセージ・タイプごとに.pb.goファイルを生成します。

概要

全ての etcd3 API は gRPC サービスで定義されており、etcd サーバが理解できるリモートプロシージャコールを分類しています。この記事では、proto3定義の概念を紹介し、gRPCインターフェースについて学ぶために必要な知識を提供します。次回は etcd3 のコアとなる gRPC API インターフェースについて紹介します。

Read next

LeetCodeの問題解決:122.株の買い時と売り時II、JavaScript、1つのループ、詳細なコメント

すでにすべての時点の株価を知っています。 必要なのは、明日の価格が今日の価格より高ければ、取引が必要であることを意味すると判断することだけです。つまり、今日買って明日売るということです。 配列を繰り返し、n+1 日目の価格が n 日目の価格より高ければ、両者の価格差に利益が加算されます。

Apr 8, 2020 · 1 min read