Apache Thrift、Google Protocol Buffers、MessagePack、ASN.1、Apache Avroの主な違いは何ですか?


124

これらはすべて、バイナリシリアル化、RPCフレームワーク、IDLを提供します。それらと特性(パフォーマンス、使いやすさ、プログラミング言語のサポート)の主な違いに興味があります。

他に同様のテクノロジーを知っている場合は、回答でそのことを述べてください。



@Zenikoder:このリンクには、5つのうち2つのクエリ形式の情報はありません。
私の正しい意見だけ正しい

それは助けることができます:slideshare.net/IgorAnishchenko/pb-vs-thrift-vs-avro
thoroc

2
RPCを知らない人向け-リモートProdecureコール、IDL-インターフェイス定義言語
garg10may

回答:


97

ASN.1はISO / ISE標準です。非常に読みやすいソース言語と、バイナリと人間が読みやすいさまざまなバックエンドがあります。国際標準であること(そして古いものであること!)、ソース言語は(大西洋が少し湿っているのとほぼ同じように)少し台所臭いですが、非常に詳細に指定されており、かなりの量のサポートがあります。(十分に掘り下げて、FFIで使用できる優れたC言語ライブラリがない場合は、名前を付けた任意の言語のASN.1ライブラリを見つけることができます)。いくつかの優れたチュートリアルも利用できます。

リサイクルは標準ではありません。これは元々はFacebookからのものであり、後にオープンソースになり、現在はトップレベルのApacheプロジェクトです。それは十分に文書化されていません-特にチュートリアルレベル-そして、私の(確かに簡単に)一見すると、他の以前の取り組みがまだ行っていない(そして場合によってはより良い)何かを追加するようには見えません。公平を期すために、比較的目立たない非主流の言語を含む、すぐに使用できるかなり多くの言語があります。IDLも漠然とCに似ています。

プロトコルバッファは標準ではありません。これは、より広いコミュニティにリリースされているGoogle製品です。そのままでサポートされる言語の点で少し制限されています(C ++、Python、Javaのみをサポートします)が、(品質が非常に変化する)他の言語に対するサードパーティのサポートはたくさんあります。Googleはほとんどすべての作業をプロトコルバッファーを使用して行うので、これは戦いでテストされ、戦いで強化されたプロトコルです(ASN.1ほど戦いで強化されていませんが、Thriftよりもはるかに優れたドキュメントがありますが、グーグル製品、それは不安定である可能性が非常に高いです(信頼できないという意味ではなく、常に変化するという意味で)IDLもCに似ています。

上記のシステムはすべて、ある種のIDLで定義されたスキーマを使用して、ターゲット言語のコードを生成し、それをエンコードおよびデコードで使用します。Avroはしません。Avroの型付けは動的であり、そのスキーマデータは実行時にエンコードとデコードの両方に直接使用されます(これには処理に明らかなコストがかかるだけでなく、動的言語に比べて明らかな利点があり、型にタグを付ける必要がないなど)。 。そのスキーマはJSONを使用しているため、JSONライブラリがすでにある場合、新しい言語でのAvroのサポートは管理が少し簡単になります。繰り返しになりますが、ホイールを再発明するほとんどのプロトコル記述システムと同様に、Avroも標準化されていません。

個人的には、私の愛/憎しみの関係にもかかわらず、RPCスタックは実際にはありません(RPCスタックを作成する必要がありますが、IOCはそれを作成しますが)十分に簡単です)。


3
詳細な説明ありがとうございます。しかし、バージョン管理についてはどうですか、protobufはそれを処理できると聞いたのですが、他のライブラリについてはどうですか?また、Avroには、JSONに加えてCに似た構文のIDLがあるようです。
andreypopp

2
ASN.1は、...拡張マーカーによる手動バージョン管理、またはEXTENSIBILITY IMPLIEDモジュールヘッダーでの自動バージョン管理をサポートしています。プロトコルバッファ、IIRCは手動バージョン管理をサポートしています。それが暗黙の拡張性のようなものをサポートするかどうかはわかりません(そしてそれを調べるのが面倒です)。Thriftはいくつかのバージョニングもサポートしていますが、暗黙の拡張性のない手動プロセスのように思われます。
私の正しい意見だけで

7
レコードの場合、プロトコルバッファは常にフィールドを数値で明示的にエンコードします。追加のフィールドがある場合、ライブラリレベルでエラーになることはなく、欠落しているフィールドがオプションまたは明示的にマークされている場合、エラーではありません。したがって、すべてのプロトコルバッファメッセージにはがありEXTENSIBILITY IMPLIEDます。
Kevin Cathcart

IOCによって-制御の反転を意味しますか?XML-RPC拡張のようなPHPのRPCスタックには何を使用しますか?それとも自分で何かを書く必要がありますか?
2012

4
Avroは、定義されたスキーマで動的に機能するか、ボイラープレートクラスを生成できるため、より柔軟です。私の経験から、それは非常に強力です。その強みは、RPCジェネレーター(これはThriftの一般的な機能です)を含む豊富な機能セットにあります。
Paolo Maresca 2014

38

シリアライザについて内部調査を行いました。ここにいくつかの結果があります(将来の参考用にも!)

スリフト=シリアル化+ RPCスタック

最大の違いは、Thriftは単なるシリアル化プロトコルではなく、現代のSOAPスタックのような本格的なRPCスタックであることです。そのため、シリアル化後、オブジェクト TCP / IPを介してマシン間で送信できます(必須ではありません)。SOAPでは、利用可能なサービス(リモートメソッド)と予期される引数/オブジェクトを完全に記述したWSDLドキュメントから始めました。これらのオブジェクトはXML経由で送信されました。Thriftでは、.thriftファイルは使用可能なメソッド、予想されるパラメーターオブジェクトを完全に記述し、オブジェクトは使用可能なシリアライザーの1つを介してシリアル化されます(Compact Protocol効率的なバイナリプロトコルで、生産で最も人気があります)。

ASN.1 =グランドパパ

ASN.1は80年代の通信関係者によって設計されたものであり、CompSci関係者から登場した最近のシリアライザと比較してライブラリサポートが制限されているため、使用するのが面倒です。DER(バイナリ)エンコーディングとPEM(ASCII)エンコーディングの2つのバリアントがあります。どちらも高速ですが、DERは高速であり、2つのうちサイズ効率が高くなります。実際、ASN.1 DERは、30年に渡って設計されたシリアライザに簡単に追いつくことができます(時にはビートすることもできます)それ自体が、その優れた設計の証です。それは非常にコンパクトで、プロトコルバッファーやスリフトよりも小さく、アブロに負けません。問題は、サポートする優れたライブラリがあることです。現在、Bouncy CastleはC#/ Javaに最適なライブラリのようです。ASN.1はセキュリティと暗号化システムの王様であり、なくなることはないので、「将来の証明」について心配する必要はありません。ちょうど良いライブラリを取得...

MessagePack =パックの真ん中

悪くはありませんが、サポートされている最速でも、最小でも、最高でもありません。それを選択する生産上の理由はありません。

一般

それを超えて、それらはかなり似ています。ほとんどは基本TLV: Type-Length-Value原理の変形です。

プロトコルバッファ(Googleが作成)、Avro(Apacheベース、Hadoopで使用)、Thrift(Facebookが作成、現在はApacheプロジェクト)、ASN.1(Telecomが作成)はすべて、最初にシリアライザでデータを表現する、ある程度のコード生成を伴います。固有の形式の場合、シリアライザ「コンパイラ」はcode-genフェーズを介して言語のソースコードを生成します。アプリのソースは、これらのcode-genクラスをIOに使用します。特定の実装(例:MicrosoftのAvroライブラリまたはMarc GavelのProtoBuf.NET)では、アプリレベルのPOCO / POJOオブジェクトを直接装飾でき、ライブラリはコード生成クラスではなく、装飾されたクラスを直接使用します。これにより、オブジェクトのコピー段階(アプリケーションレベルのPOCO / POJOフィールドからコード生成フィールドまで)がなくなるため、パフォーマンスが向上することがわかりました。

いくつかの結果と遊ぶプロジェクト

このプロジェクト(https://github.com/sidshetye/SerializersCompare)は、C#の世界で重要なシリアライザーを比較します。Javaの人々はすでにようなものを持っています。

1000 iterations per serializer, average times listed
Sorting result by size
Name                Bytes  Time (ms)
------------------------------------
Avro (cheating)       133     0.0142
Avro                  133     0.0568
Avro MSFT             141     0.0051
Thrift (cheating)     148     0.0069
Thrift                148     0.1470
ProtoBuf              155     0.0077
MessagePack           230     0.0296
ServiceStackJSV       258     0.0159
Json.NET BSON         286     0.0381
ServiceStackJson      290     0.0164
Json.NET              290     0.0333
XmlSerializer         571     0.1025
Binary Formatter      748     0.0344

Options: (T)est, (R)esults, s(O)rt order, (S)erializer output, (D)eserializer output (in JSON form), (E)xit

Serialized via ASN.1 DER encoding to 148 bytes in 0.0674ms (hacked experiment!)

3
ASN.1には、BER(基本エンコーディングルール)、PER(パックエンコーディングルール)、およびXER(XMLエンコーディングルール)もあります。DERはBERのバリエーションであり、データムごとに一意のエンコーディングを保証するため、主に暗号化に使用されます。BERとPERはどちらもDERよりも効率的です。ほとんどのライブラリはDERを処理します。一部のBERコンストラクトは正しく処理されません。もっと知りたい人のために:luca.ntop.org/Teaching/Appunti/asn1.html
Joe Steele

また、JER(JavaScript Object Notation Encoding Rules)もあります。ECN(Encoding Control Notation)を使用して独自のエンコーディングルールを定義することもできます。ダウンロードリンク付きの仕様の良いリスト:oss.com/asn1/resources/standards-define-asn1.html
Dmitry

There are two variants, DER (binary) encoding and PEM (ascii) encoding。PEMはBEGIN ENDコメント内のbase-64エンコードされたバイナリデータにすぎないことに注意してください。このバイナリデータはDERエンコーディングを使用して生成された可能性があるため、PEMとDERを比較するのはおかしいです。
RafalS

14

パフォーマンスの観点に加えて、Uberは最近、エンジニアリングブログでこれらのライブラリのいくつかを評価しました。

https://eng.uber.com/trip-data-squeeze/

彼らの勝者は?MessagePack +圧縮用zlib

私たちの目標は、エンコードプロトコルと圧縮アルゴリズムの組み合わせを見つけ、最も高速で最もコンパクトな結果を出すことでした。Uber New York Cityからの2,219の擬似ランダムな匿名化された旅行(JSONとしてテキストファイルに入力)で、エンコードプロトコルと圧縮アルゴリズムの組み合わせをテストしました。

ここでの教訓は、要件によって、どのライブラリが適切かを決定するということです。Uberの場合、スキーマを使用しないメッセージパッシングの性質のため、IDLベースのプロトコルを使用できませんでした。これにより、多数のオプションが排除されました。また、彼らにとって重要なのは、生のエンコード/デコード時間だけでなく、保存されているデータのサイズでもあります。

サイズ結果

サイズ結果

スピード結果

ここに画像の説明を入力してください


13

ASN.1の大きな点の1つは、これは仕様で はなく、実装でいることです。したがって、「実際の」プログラミング言語での実装の詳細の非表示/無視は非常に優れています。

エンコードルールをasn1-fileに適用し、その両方から実行可能コードを生成するのは、ASN.1-Compilerの仕事です。エンコーディングルールは、EnCoding Notation(ECN)で指定される場合と、BER / DER、PER、XER / EXERなどの標準化されたものの1つである場合があります。つまり、ASN.1はタイプと構造であり、エンコードルールはオンザエンコードを定義し、コンパイラはそれをプログラミング言語に転送します。

無料のコンパイラは、私の知る限り、C、C ++、C#、Java、およびErlangをサポートしています。(非常に高価で特許/ライセンスが付与されている)商用コンパイラは非常に用途が広く、通常は完全に最新で、時にはさらに多くの言語をサポートしますが、サイト(OSS Nokalva、Marbenなど)を参照してください。

この手法を使用して、まったく異なるプログラミングカルチャー(たとえば、「組み込み」の人々と「サーバーファーマー」)の関係者間のインターフェースを指定するのは驚くほど簡単です。 。それがどのように実装されるかを心配する必要はありません。誰もが「自分のもの」を使用できるようにしてください!私にとってはとてもうまくいきました。ところで:OSS Nokalvaのサイトでは、ASN.1について少なくとも2冊の無料でダウンロードできる本を見つけることができます(1つはLarmouth、もう1つはDubuisson)。

私見の他の製品のほとんどは、直列化の問題に大量の空気を送り込む、まだ別のRPCスタブジェネレーターになることだけを試みています。まあ、それが必要な場合は、大丈夫かもしれません。しかし、私には、それらはSun-RPCの再発明(80年代後半から)のように見えますが、ねえ、それもうまくいきました。


7

MicrosoftのBond(https://github.com/Microsoft/bond)は、パフォーマンス、機能、およびドキュメントが非常に印象的です。ただし、現時点(2015年2月13日)では、多くのターゲットプラットフォームをサポートしていません。それは非常に新しいからだと思います。現在、python、c#、c ++をサポートしています。MSの至るところで使用されています。私はそれを試してみました、ボンドを使用するC#開発者はprotobufを使用するよりも優れていますが、私はリサイクルも使用しました。私が直面した唯一の問題はドキュメントに関するものでした。

(次のように債券には、いくつかのリソースがあるhttps://news.ycombinator.com/item?id=8866694https://news.ycombinator.com/item?id=8866848https://microsoft.github.io/ bond / why_bond.html


5

パフォーマンスのために、1つのデータポイントはjvm-serializersベンチマークです。これは非常に具体的で小さなメッセージですが、Javaプラットフォームを使用している場合は役立つ場合があります。パフォーマンス全般は、多くの場合、最も重要な違いではないと思います。また、著者の言葉を福音にしないでください。宣伝されている主張の多くは偽物です(たとえば、msgpackサイトには疑わしい主張がいくつかあります。速いかもしれませんが、情報は非常に大ざっぱで、ユースケースはあまり現実的ではありません)。

大きな違いの1つは、スキーマを使用する必要があるかどうかです(少なくともPB、Thrift、Avroはオプションである可能性があります。ASN.1と思います。MsgPack、必ずしもそうとは限りません)。

また、私の意見では、レイヤー化されたモジュラー設計を使用できるのは良いことです。つまり、RPCレイヤーはデータ形式やシリアル化を指示すべきではありません。残念ながら、ほとんどの候補者はこれらをしっかりとバンドルしています。

最後に、データ形式を選択するとき、今日のパフォーマンスはテキスト形式の使用を排除していません。非常に高速なJSONパーサー(およびかなり高速なストリーミングXMLパーサー)があります。また、スクリプト言語の相互運用性と使いやすさを考慮すると、バイナリ形式とプロトコルは最適な選択ではない場合があります。


経験を共有していただきありがとうございます。私はまだバイナリ形式が必要だと思います(本当に大量のデータがあります)。おそらくAvroを使い続けるでしょう。
andreypopp

そうだね。使用するフォーマットに関係なく、任意のレートで圧縮を使用することをお勧めします(gzip / deflateに比べて、圧縮/解凍は非常に高速であるため、LZFは優れています)。
StaxMan '13年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.