ミートボンド、マイクロソフトボンド-新しいデータシリアル化フレームワーク
公開: 2022-03-11Microsoft Bondは、Microsoftによって作成されたスキーマ化されたデータの新しいシリアル化フレームワークです。
データのシリアル化が最もよく使用される場所を要約してみましょう。
- ファイル、ストリーム、NoSQL、BigDataでのデータの永続性。
- ネットワーク、IPCなどでのデータ送信。
通常、これらのアプリケーションはスキーマ化されたデータを処理する必要があります。スキーマとは次のことを意味します。
- 構造:階層、関係、順序。
- セマンティック:生まれてからの年数での年齢。
実際には、プログラミング言語によって暗黙的に定義またはサポートされている場合でも、データにはスキーマがあります。 複雑なデータ構造になると、サポートするデータ転送オブジェクト(DTO)とIOを担当するコードを、多くの場合異なる言語で作成することになります。 それが成長して進化するとすぐに、これらすべての部品を維持することはすぐに悪夢になります。 ここで、シリアル化フレームワークがゲームに勝ちます。
まず、シリアル化フレームワークは、特定のプログラミング言語またはプラットフォームにバインドされていないデータスキーマ定義の抽象化を定義します。 この抽象化はDSL(ドメイン固有言語)として知られています。
このようなDSLを使用すると、特定のアプリケーションのデータスキーマを定義できます。 次に、定義は複数の形式で表現できますが、多くの場合、シリアル化フレームワークは、DSLに適した単一の形式をサポートします。 複雑すぎる? よく知られている例を次に示します。XSDとXMLです。
XSDはDSLを定義し、XMLは(推奨)XSDスキーマに一致するドキュメントを定義します。 ただし、「xsd.exe」を使用してXSDに一致するDTOクラスを生成することもできるため、生成されるクラスは単なる別の形式です。 DTOからXMLを生成することも、その逆も可能であり、セマンティクスは一般的であるため、セマンティクスは同じであることに注意してください。XSDで定義されます。 要約すると、シリアル化フレームワークはDSLを提供します。これを使用して、特定のフレームワークで最適にサポートされる特定の形式でデータスキーマを定義します。
抽象データスキーマは、最終的にプログラミング言語で表現された一連のエンティティに具体化されます。 すべてのシリアル化フレームワークは、コードジェネレーターと呼ばれる特別なツールを提供します。
これらは、クライアントがスキーマ化されたデータ(DTO、プロキシなど)を操作するために必要な、ターゲットプログラミング言語のすべてのサポートコードを生成します。これは、最終的には厳密に型指定された言語に必要ですが、ダック型(動的)言語にはオプションです。 。
最後に重要なのは、ネットワーク上のデータの永続性です。 実際のデータは、最終的にrawバイト(またはテキスト)にシリアル化され、逆シリアル化されます。
すべてのデータシリアル化フレームワークは、ここではプロトコルと呼ばれる別の抽象化を提供します。 プロトコルは、構造化データをそのスキーマに従ってシリアル化または逆シリアル化する方法を定義する一連のルールを定義します。 各プロトコルは通常、特定のシリアル化フレームワークでサポートされているすべてのプログラミング言語とプラットフォームに実装されています。 サポートするプログラミング言語/プラットフォームが多いほど、提供する実装も多くなります。
フレームワークがJSONプロトコルをサポートすることをいとわない場合、C#、C ++、Windows、LinuxなどのJSONリーダー/ライターを提供する必要があると想像してください。
すべてをまとめると、最新のデータシリアル化フレームワークは次の機能を提供します。
- 抽象化:DSLとプロトコル。
- コード生成ツール。
- プロトコルの実装。
Microsoft Bondは、最新のデータシリアル化フレームワークです。 強力なDSLと柔軟なプロトコル、C ++およびC#用のコードジェネレーター、Windows、Linux、およびMacOSX用の効率的なプロトコル実装を提供します。
数年間、Bondは内部使用のみのテクノロジーであり続けましたが、Microsoftオープンソースイニシアチブのおかげで、BondはGitHub:MicrosoftBondで利用できるようになりました。
データシリアル化の競合他社
ソフトウェアの巨人の間の競争により、いくつかのシリアル化フレームワークが登場しました。
- GoogleInc.-Googleプロトコルバッファ
- FacebookInc.-現在Apacheによって保守されているThrift
- ApacheFoundationソフトウェア-Avro
明らかに、これらはすべて互換性がありません。これらのいずれかを使用してパブリックAPIを作成しない限り、問題ありません。
それぞれに長所と短所があるので、ニーズに基づいてそれらから選択できます。
なぜボンド?
この質問に対する公式の答えはここにあります:「なぜボンド」。
簡単な要約は次のとおりです。
- ボンドはジェネリックスを含むリッチタイプシステムをサポートしています。
- Bondは、スキーマのバージョン管理と双方向の互換性をサポートしています。
- Bondは、ランタイムスキーマ操作をサポートします。
- ボンドはさまざまなコレクションをサポートしています。
、地図 、リスト 」。 - ボンドはタイプセーフなレイジーシリアル化をサポートします。
」 - Bondは、マーシャリングとトランスコーディングを備えたプラグ可能なプロトコル(フォーマット)をサポートします
重要な注意点は、ボンドは「ペイ・トゥ・プレイ」戦略に従っているということです。 追加/使用する機能が多いほど、サイズと速度に対してより多くの費用がかかります。 これにより、開発者は大きな柔軟性を得ることができます。
正直に言って、欠点も挙げましょう。
- Bondは、C ++とC#をサポートするMicrosoftスタックを対象としていますが、Javaは(まだ)サポートしていません。
- ボンドは共用体タイプ(protobufの「oneof」)をサポートしていません。
パフォーマンスはどうですか?
あるフレームワークを別のフレームワークと比較する場合、開発者はパフォーマンスの比較を求めていることがよくあります。 ただし、これらのフレームワークはDSL、コードジェネレーター、およびプロトコルで構成されていることを思い出してください。 プロトコルのパフォーマンスのみを考慮すると、DSLとcodegensによって提供される機能を見逃すことになります。 場合によっては、シリアル化の速度に数パーセントの違いがあるよりも、DSLの方がはるかに重要です。
速度以外に、一部のプロトコルでサポートされているスペース効率の高いエンコーディングも重要になる可能性があります。 ドメイン固有のデータとパフォーマンス/スペースを比較することをお勧めします。 これは、特定のフレームワークから得られるすべてのメリットを見積もる唯一の方法です。

この記事には、Windowsアプリケーションイベントログからすべてのレコードを読み取り、それらをBondオブジェクトとしてシリアル化し、逆シリアル化することにより、Bondフレームワークの使用法を示すデモプロジェクトが付属しています。
デモをビルドして実行するために、VisualStudio以外のソフトウェアをインストールする必要はありません。
MicrosoftBondの使用
絆を得る
プラットフォームのBondの入手に関する公式ガイドを確認してください。
.NETプロジェクトの場合、これは次のように簡単です。
install-package Bond.CSharp
パッケージに含まれるもの:
- binフォルダー内のコードジェネレーター(gbc.exe)
- .NETライブラリ
- MSBuildタスク
ワークフロー
ワークフローには、次の手順が含まれます。
- DSLを学び、「。bond」ファイルを作成してデータスキーマを定義します。
- コードジェネレーター(「gbc.exe」)を使用して、プログラミング言語のDTOを取得します。
- プロジェクト内の生成されたファイルとBondランタイムライブラリを参照します。
フレームワークで提供されるMSBuildタスクを使用して、コード生成ステップを自動化することを検討してください。
DSL機能の概要
最初の「.bond」ファイルの作成を開始するときは、その構文と機能を知っておく必要があります。 IDLの詳細を説明している公式ドキュメントページをご覧ください。 基本的な機能だけを確認しましょう。
- モジュール:スキーマは、「import」ステートメントに含まれているさまざまなファイルに分割できます。
- 名前空間:C ++ / C#と同じ意味です。
- ユーザー定義の構造体:ユーザータイプ定義の単位。
- 前方宣言は、再帰的なデータ構造に役立ちます。
- 基本タイプ:「bool、uint8(から64)、int8(から64)、float、double、string、wstring」。
- コンテナタイプ:「blob、list
、ベクトル 、 セットする 、map <K、T>、null許容 」。 - カスタムタイプのエイリアスとマッピング。たとえば、C#で「DateTime」を使用したいが、ネットワーク上でティック(「int64」)を使用したい場合。
- カスタム属性:カスタムコード生成に役立ちます。
退屈? 次に例を示します。
namespace MyProject struct MyRecord { 0: string Name = "Noname"; 1: vector<double> Constants; }
ここで、「0」と「1」はフィールドの序数(任意のペースの任意の整数)であり、 = "Noname"
は(オプションの)デフォルト値です。
コード生成
ボンドフレームワークは、Haskellで書かれたコード生成ツールを提供します。 コマンドラインで「.bond」スキーマからC#およびC++コードを生成する方法は次のとおりです。
gbc c# example.bond gbc c++ example.bond
サポートされているプロトコル(フォーマット)
すぐに使用できるBondは、次の3種類のプロトコルをサポートしています。
- タグ付きプロトコル:「CompactBinary」および「FastBinary」
タグ付きプロトコルは、ペイロード内のスキーマメタデータをインターリーブします。 これにより、ペイロードが自己記述型になり、プロデューサーが使用するスキーマを知らなくても、コンシューマーがペイロードを解釈できるようになります。
- タグなしプロトコル:「SimpleBinary」
タグなしプロトコルはデータのみをシリアル化するため、コンシューマーは帯域外メカニズムを介してペイロードスキーマを知っている必要があります。 タグなしプロトコルは、スキーマを1回(データベースのシステムテーブルなどに)格納できるため、ストレージシナリオでよく使用されます。これにより、同じスキーマを使用する多くのレコードからメタデータのオーバーヘッドが排除されます。
- DOMベースのプロトコル:「SimpleJson」および「SimpleXml」
DOMベースのプロトコルは、ペイロード全体をメモリ内のデータオブジェクトモデルに解析します。このモデルは、逆シリアル化中にクエリされます。 通常、この種のプロトコルは、JSONやXMLなどのテキストベースのエンコーディングを実装するために使用されます。
プロトコルごとに、Bondランタイムライブラリは、実際のシリアル化でジョブを実行する、対応するReaderクラスとWriterクラスを提供します。
プロトコルの使用は非常に簡単で、有名な「JsonConvert.SerializeObject()」よりも少し難しいです。
var record = new MyRecord { Name = "FooBar", Constants = { 3.14, 6.28 } }; var output = new OutputBuffer(); var writer = new CompactBinaryWriter<OutputBuffer>(output); Serialize.To(writer, record); var input = new InputBuffer(output.Data); var reader = new CompactBinaryReader<InputBuffer>(input); record = Deserialize<Example>.From(reader);
次は何ですか?
ボンドが好きで、コーディングに十分な時間があれば、これらのアイテムの1つを開発に取り入れることを検討してください。 貢献することで得られるすべてのメリットを列挙することはしませんが、多くの開発者が貢献するアイデアを探していることは知っています。
- Javaへのポートを実装します。 選択した他の主流言語にJavaを置き換えます。
- 他のDSLと交換するためにBondスキーマのインポート/エクスポートを実装します(例:「。proto <=>。bond」)。
ボンドに関して何をするにしても、最初にアダム・サペックに連絡することをお勧めします。 彼はこのプロジェクトのリーダーであり、市場で最も要求されているものを案内します。