1. 効率的なデータのシリアライズを求めて
とあるプロジェクトで、Dockerコンテナ上で動くWEBアプリケーションを開発しています。 それぞれのコンテナは互いに通信を行う必要があります。 どのようなデータのシリアライズフォーマットが良いか、調べて見ることにしました。
Web APIと言えばJSONでやり取りするREST APIが主流ですね。 JSONやXMLは人間でも読みやすいデータ形式ですので、その点はとても大きな利点です。 しかし、データサイズという点においては、JSONやXMLはあまり良くありません。
頻繁にやり取りを行うAPIになればなるほど、データサイズやレスポンススピードは重要になってきます。
2. データのシリアライズフォーマット
4種類のデータ・シリアライズフォーマットを比較してみたいと思います。
2.1 Protocol Buffers
Protocol BuffersはGoogleによって開発され、2001年にリリースされました。 データサイズはJSONやXMLよりもはるかに小さいです。 Google, Square, Netflix, Docker, Ciscoなど多くの企業が採用しています。
直感的なスキーマ
.proto
ファイルと呼ばれるスキーマファイルを使用します。
APIとデータ定義などのインターフェースをここに定義します。
シンタックスはシンプルで直感的で、JSONスキーマよりもずっと理解しやすいです。
.proto
ファイルを作成した後、 .proto
ファイルをコンパイルすると
自動的にインターフェースのコードが生成されます。
あとはクライアントとサーバ側のコードを書けば良いだけなので、とてもシンプルです。
gRPCがWebブラウザにも対応
gRPCとは、Protocol Buffersを用いてRPC通信を行うプロトコルです。 このgRPCもGoogleによって開発されたもので、Googleの巨大なインフラで使用されています。
つい先日、gRPC-web というものが公開され、WebブラウザからでもgRPC通信が可能になりました。 gRPCがREST APIに変わる通信になる可能性も感じますね。
参考リンク:
2.2 Apache Thrift
Apache Thrift(アパッチ スリフト)は、「スケーラブルな言語間サービス開発」のためにFacebookにて開発された遠隔手続き呼出し (RPC) フレームワークである。 (from: wikipedia)
Thriftは当初Facebookによって開発されていましたが、現在はApacheのもとで開発されています。 facebook、Cassandra、Twitter、EvernoteなどがThriftを採用しています。
Protocol Buffersと同様、IDL(インターフェース定義言語)を用いてスキーマを定義します。また、パフォーマンスもとても良い結果を出しています。
- Thrift vs Protocol Buffers vs Avro - Biased Comparison
- Apache Thrift vs Protocol Buffers vs Fast Buffers
2.3 MessagePack
MessagePack is a computer data interchange format. It is a binary form for representing simple data structures like arrays and associative arrays. (from: wikipedia)
MessagePackはJSONに似ていますが、ずっと高速でシンプルです。 とても使いやすく、多くの言語からもサポートされています。
redis、fluentd、Treasure Data、Pinterestが採用しています。
参考リンク:
2.4 FlatBuffers
FlatBuffers is a free software library implementing a serialization format similar to Protocol Buffers, (from: wikipedia)
FlatBuffersはGoogleによって開発され、2014年にリリースされました。比較的最近ですね。
下記の参考リンクを見ると、いくつかのウェブサイトにおいては、他のシリアライズ方式よりも良いパフォーマンスを出しているようです。 しかし、FlatBuffersは開発するのが他のものに比べて少し大変なため、 相当な大きさのデータをやり取りするケースに用いるのが良さそうに思いました。
参考リンク:
3. 結論: Protocl Buffers/gRPCを採用
結果、Protocol Buffersを用いたgRPCを採用することにしました。
理由はまず第一に十分なパフォーマンスで動作する事です。XMLやJSONに比べて圧倒的にデータ量も少なくできます。
次に、Protocol Buffersのスキーマがとても直感的で、長期的な開発という観点で良いと判断しました。 開発してから数ヶ月後にAPIのスキーマを見返したときに、どのスキーマが分かりやすいでしょうか。 長く開発していく上で、Protocol Buffersのスキーマが途中参加したチームメンバーにも分かりやすいというのは大きな利点です。
さらに、多くの企業がProtocol BuffersとgRPCを採用し始めており、十分に使われているため ドキュメントやサンプルが豊富である点もプラスでした。
また、新しく発表された gRPC-webも決断を後押ししました。 今後、フロントエンドから直接gRPC経由でメソッドコールを行う可能性もあるかも知れません。
ということで、私のチームでは Protocol Buffers / gRPC を用いて開発していく事に決まりました。 もし何かいろいろ気づいた点などあれば、ここでシェアしていきたいと思います👍
by @takp