フラミナル

考え方や調べたことを書き殴ります。IT技術系記事多め

gRPCをとにかくわかりやすく丁寧に説明します

f:id:lirlia:20200417164540p:plain

この記事ではgRPCをとにかくわかりやすく説明します。

gRPCとは?

まず正しい定義を書きます。(最初は理解が難しいので流してください)

  • gRPCはGoogleが作ったRPCです
  • HTTP/2の上で動作します
  • Protocol Buffersを使ってデータをシリアライズ化します
  • protoファイルと呼ばれるIDL(Interface Definition Language)でAPI仕様を規定します

この記事を通じて、これらが何を示しているのかを理解していきましょう。

まずはRPCを知ろう

RPCはRemote Procedure Callと呼ばれる古くから存在する技術です。RPCを使うことでリモート(Remote)にある関数/手続き(Procedure)を呼ぶ(Call)ことができます。文脈によっては個別の規格を指す場合がありますが、この記事の中では総称として用いています。


この一連の流れをRPCといいます。(NFSもRPCをつかっています)

f:id:lirlia:20200417232120p:plain

RPCの課題

RPCにはいくつかの問題がありました

  • 性能
    • ネットワーク越しに関数を呼ぶと時間がかかる
  • データ型変換
    • 言語ごとにサポートする型が違うため変換ができない
  • 負荷分散の問題
    • 当時はサーバ1台とクライアント3台。といった決まった構成を前提に動かすシステムだったため、サーバ側にクライアントの状態を保持しており大規模な分散システムには利用ができない

RPCについてはこちらの書籍にて紹介されています。

gRPCとはなんなのか?

gRPCはGoogleが開発したRPC(Google Protocol RPC)で、HTTP/2の上でデータのやりとりをするプロトコル・規約です。

私たちが普段ブラウザで動画やブログ記事を見ている時は以下の図のような通信が行われています。

f:id:lirlia:20200417232720p:plain

HTTPリクエストの中にアクセスしたいURLが含まれており、レスポンス(返事)に取得した記事(HTML)が含まれています。これをブラウザが解釈して記事が表示されています。

gRPCの場合はHTTP/2と呼ばれる進化したHTTPプロトコルを利用して通信を行います。やっていることは先ほどとほとんど同じに見えますね。違うのはHTTPを使ってリモートの関数を呼んでいるところですかね。

f:id:lirlia:20200417233122p:plain

まずこの2つがわかりましたね。

  • gRPCはGoogleが作ったRPCです
  • HTTP/2の上で動作します
  • Protocol Buffersを使ってデータをシリアライズ化します
  • protoファイルと呼ばれるIDL(Interface Definition Language)でAPI仕様を規定します

シリアライズ化とProtocolBuffersとは?

急によくわからない単語がでてきました。大丈夫です、きちんと説明します。

シリアライズ化とは

ここでいうシリアライズ化とは「オブジェクトをバイナリデータに変換する処理」のことです。またよくわからない表現が出てきましたね。


こんな変数を作ったとします。

{
    'age': 30,
    'name': 'taro'
}

この変数は name = taroage = 30 が設定されたオブジェクト(なんらかのモノのこと)です。これをシリアライズ化するとこんな風になります。(シリアライズ化するツールやライブラリによって結果は変わります)

(dp0
S'age'
p1
I30
sS'name'
p2
S'taro'
p3
s.

今回の変数は非常にシンプルなため本当はシリアライズ化が不要なのですが、オブジェクトの中にはメモリのアドレスを保有していたりオブジェクトIDなどそのまま文字列化しても意味がない場合があります。その際は、変数をそのまま出力するのではなくバイナリ化するシリアライズ化が必要となります。

一体なぜシリアライズ化が必要なのか?

シリアライズ化することで本来そのアプリでしか使用できないオブジェクトを他に渡すことができるようになるからです。ちなみに、シリアライズ化されたデータを元に戻すことをデシリアライズ化と呼びます。

またシリアライズ化することによってデータ量が削減されます。

gRPCでのシリアライズ化

gRPCではクライアントとサーバ間でやりとりするデータを「シリアライズ化」しています。そしてそのときに使っているシリアライズ化の手法が「Protocol Buffers」です。

ここまできました。あともう少しです。

  • gRPCはGoogleが作ったRPCです
  • HTTP/2の上で動作します
  • Protocol Buffersを使ってデータをシリアライズ化します
  • protoファイルと呼ばれるIDL(Interface Definition Language)でAPI仕様を規定します

実際に試してみよう

続いてはgRPCについて実際にやってみて理解を進めましょう。このハンズオンの中でprotoファイルの説明が行われます。

blog.framinal.life

protoファイルとはサーバで公開する関数の仕様を規定するファイルです。このファイルを使ってクライアント・サーバがgRPCを行うためのコードを生成することができます。

1種類のprotoファイルから様々な言語のコードを生成することができるため、protoファイルのみを作成することで多言語なアプリ間でのRPC通信を実施することができるようになります。

  • gRPCはGoogleが作ったRPCです
  • HTTP/2の上で動作します
  • Protocol Buffersを使ってデータをシリアライズ化します
  • protoファイルと呼ばれるIDL(Interface Definition Language)でAPI仕様を規定します

gRPCの通信の流れ

上記のハンズオンの中でsayHello関数をgRPCで呼び出した時の動きを図解化します。

まずはクライアント側で呼び出しが行われます。この時protoファイルによって生成されたhelloworld_pb2.pyhelloworld_pb2_grpc.pyのコードによってgRPCに変換されHTTP/2でコネクションが張られます。

f:id:lirlia:20200418000923p:plain


サーバ側では受け取ったgRPCメッセージをデシリアライズ化しserver.pyに渡します。

f:id:lirlia:20200418001151p:plain


返却も同様にシリアライズ化され行われます。

f:id:lirlia:20200418001152p:plain

まとめ

今回紹介しきれていませんがgRPCを使った時のメリットは以下の通りです

  • HTTP/2やProtocol Buffersを使うことによるパフォーマンスが向上する
  • 開発者はAPiをコールする処理を書くときやAPIを用意するときにprotoファイルのみを意識すればよいので非常に楽になる(HTTP/2の恩恵も預かれる)
  • シチュエーションに応じた複数の言語を採用しやすくなる(各言語で作ったアプリ間の通信をgRPCに統一すればよいので)
  • gRPCの仕様が厳格に規定されているためブレにくい

すでにGoogle社では社内で全般的に利用されているとのことですし、Web系の企業では利用が進んでいるということなのでこれからはやっていきそうですね。