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

StackOverflow https://stackoverflow.com/questions/4633611

質問

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

他の同様のテクノロジーを知っている場合は、回答で言及してください。

役に立ちましたか?

解決

ASN.1 ISO/ISE標準です。非常に読みやすいソース言語と、バイナリと人間の読み取り可能なさまざまなバックエンドがあります。国際的な標準である(そしてその時代!)ソース言語は少しキッチンシンクでした(大西洋が少し濡れているのとほぼ同じ方法で)が、非常によく指定されており、まともな量のサポートがあります。 (おそらく、十分に掘り下げた場合、名前を付けた言語のasn.1ライブラリを見つけることができます。いくつかの良いチュートリアルも利用できます。

rif約 標準ではありません。もともとFacebookからであり、後にオープンソースであり、現在はトップレベルのApacheプロジェクトです。それは十分に文書化されていません - 特にチュートリアルレベル - そして、私の(明らかに簡単な)一目は、他の努力がまだしていないものを追加していないように見えます(そして場合によってはより良い)。それに公平を期すために、それは、いくつかの高プロファイルの非メインストリームを含む、箱から出してサポートするかなり印象的な数の言語を持っています。 IDLも漠然とC様です。

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

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

個人的には、私の愛/憎しみの関係にもかかわらず、私はおそらくほとんどのRPCとメッセージ伝送の目的でASN.1を使用しますが、実際にはRPCスタックはありません(あなたはそれを作る必要がありますが、IOCはそれを作ります十分に単純)。

他のヒント

私たちはシリアル化師について内部研究をしたばかりですが、ここにいくつかの結果があります(私の将来の参考のためにも!)

thrift = serialization + rpcスタック

最大の違いは、Thriftは単なるシリアル化プロトコルではなく、完全に吹き飛ばされたRPCスタックであり、現代の石鹸スタックのようなものです。したがって、シリアル化の後、オブジェクト たぶん......だろう (ただし、義務付けられていません)TCP/IPを介してマシン間で送信されます。 SOAPでは、利用可能なサービス(リモートメソッド)と予想される引数/オブジェクトを完全に説明するWSDLドキュメントから始めました。これらのオブジェクトはXMLを介して送信されました。 Thriftでは、.thriftファイルは、利用可能な方法、予想されるパラメーターオブジェクト、およびオブジェクトが利用可能なシリアル化師の1つを介してシリアル化されている( Compact Protocol, 、効率的なバイナリプロトコル、生産で最も人気があります)。

ASN.1 =グランドパパ

ASN.1は80年代にテレコムの人々によって設計され、 気まずい COMPSCIの人々から出現した最近のシリアルザーと比較して、図書館のサポートが限られているために使用します。 2つのバリアント、der(バイナリ)エンコードとpem(ascii)エンコードがあります。どちらも高速ですが、derはより速く、2つのうちのサイズ効率が高くなります。実際、asn.1 derは、設計されたシリアルザーを簡単に追いつくことができます(時には鼓動します) 30年 それだけで、それは十分に設計されたデザインの証です。それは非常にコンパクトで、プロトコルバッファーよりも小さく、rif約であり、Avroにbeatられただけです。問題は、サポートする優れた図書館を持っていることであり、現在、弾力のある城はC#/Javaにとって最高の城のようです。 ASN.1はセキュリティおよび暗号システムの王であり、消えることはないので、「将来の証明」を心配しないでください。良いライブラリを手に入れてください...

MessagePack =パックの中央

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

一般

それを超えて、それらはかなり似ています。ほとんどは基本のバリエーションです TLV: Type-Length-Value 原理。

プロトコルバッファー(Google Originated)、Avro(Apacheベース、Hadoopで使用)、Thrift(Facebook Originated、Now Apache Project)、ASN.1(Telecom Originated)はすべて、シリアルエイザーで最初にデータを表現するコード生成を伴います。 - 特異的な形式、その後、シリアイザー「コンパイラ」があなたの言語のソースコードを生成します。 code-gen 段階。アプリソースはこれらを使用します code-gen IOのクラス。特定の実装(例:MicrosoftのAvro LibraryまたはMarc GavelのProtobuf.net)がアプリレベルPoco/Pojoオブジェクトを直接飾ることができ、ライブラリはコードGenのクラスではなく装飾されたクラスを直接使用することに注意してください。オブジェクトのコピー段階を排除するため、このオファーはブーストパフォーマンスを提供しています(アプリケーションレベル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!)

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

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

彼らの勝者?メッセージパック + Zlibの圧縮用

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

ここでの教訓は、あなたの要件がどのライブラリがあなたに適しているかを推進することです。 Uberの場合、メッセージが通過するメッセージの概観の性質により、IDLベースのプロトコルを使用できませんでした。これにより、たくさんのオプションが排除されました。また、彼らにとっては、作用するのは生のエンコード/デコード時間だけでなく、安静時のデータのサイズです。

サイズの結果

Size Results

速度の結果

enter image description here

asn.1についての1つの大きなことは、istが設計されていることです 仕様 いいえ 実装。したがって、「実際の」プログラミング言語の実装の詳細を隠す/無視するのは非常に優れています。

ASN.1コンパイラの仕事は、エンコードルールをASN1-FILEに適用し、両方の実行可能コードから生成します。エンコーディングルールは、エンコード表記(ECN)に与えられるか、BER/DER、PER、XER/EXERなどの標準化されたルールの1つである可能性があります。それはasn.1がタイプと構造であり、エンコーディングルールはワイヤーエンコードを定義し、最後になりますが、コンパイラはプログラミング言語に転送します。

無料のコンパイラは、私の知る限り、C、C ++、C#、Java、およびErlangをサポートしています。 (高価で特許/ライセンスに乗っている)コマーシャルコンパイラは非常に用途が広く、通常は絶対に最新であり、さらに多くの言語をサポートしますが、サイト(OSS Nokalva、Marbenなど)をご覧ください。

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

私見他の製品のほとんどは、まだ別のRPCスタブ生成者であることを試み、シリアル化の問題に大量の空気を送り出します。まあ、それが必要な場合は、大丈夫かもしれません。しかし、私にとっては、彼らはSun-RPCの再発明のように見えます(80日後半から)が、それはうまくいきました。

マイクロソフトの絆(https://github.com/microsoft/bond)パフォーマンス、機能、ドキュメントで非常に印象的です。ただし、現時点では多くのターゲットプラットフォームをサポートしていません(2015年2月13日)。私はそれが非常に新しいからだと思うことしかできません。現在、Python、C#、C ++をサポートしています。それはどこでもMSによって使用されています。 AC#開発者を使用してAC#開発者がProtobufを使用するよりも優れているので、私はそれを試しましたが、私もThriftを使用しましたが、私が直面した唯一の問題はドキュメントで、私は物事がどのように行われるかを理解するために多くのことを試みなければなりませんでした。

債券に関するリソースはほとんどありません(次のとおり) https://news.ycombinator.com/item?id=8866694 , https://news.ycombinator.com/item?id=8866848 , https://microsoft.github.io/bond/why_bond.html )

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

1つの大きな違いは、スキーマを使用する必要があるかどうかです(少なくともPB、rif約; avroはオプションである可能性があります。

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top