Microsoft Bond – 一个新的数据序列化框架

本文概述

  • 数据序列化竞争对手
  • 为什么要Bond?
  • 表现如何?
  • 使用Microsoft Bond
  • 下一步是什么?
Microsoft Bond是由Microsoft创建的用于模式化数据的新序列化框架。
让我们回顾一下数据序列化最常用的位置:
  • 文件, 流, NoSQL和BigData中的数据持久性。
  • 网络, IPC等中的数据传输
通常, 这些应用程序必须处理模式化数据, 其中模式表示:
  • 结构:层次结构, 关系, 顺序。
  • 语义:出生后的年龄。
Microsoft Bond – 一个新的数据序列化框架

文章图片
实际上, 即使你的编程语言已隐式定义或支持任何数据, 也具有架构。当涉及复杂的数据结构时, 我们最终会以不同的语言编写支持数据传输的对象(DTO)和负责IO的代码。随着它的成长和发展, 它很快成为维护所有这些部件的噩梦。这是序列化框架取胜的地方。
首先, 任何序列化框架都为数据模式定义定义了一个抽象, 该抽象未绑定到特定的编程语言或平台。这种抽象称为DSL(特定领域语言)。
有了这样的DSL, 我们可以为特定的应用程序定义数据模式。反过来, 该定义可以多种形式表示, 但是序列化框架通常支持一种非常适合其DSL的单一形式。太复杂?这是一个著名的示例:XSD和XML。
XSD定义了DSL, (建议)使用XML定义与XSD架构匹配的文档。但是, 你也可以使用” xsd.exe” 生成与XSD匹配的DTO类, 因此生成的类只是另一种形式。请注意, 你可以从DTO生成XML, 反之亦然, 它们在语义上是相同的, 因为语义是通用的:它是由XSD定义的。总而言之, 序列化框架为你提供了DSL, 你可以使用它来以给定框架最支持的某种格式定义数据模式。
最终应将抽象数据模式具体化为以编程语言表示的一组实体。所有序列化框架都提供称为代码生成器的特殊工具。
它们生成目标编程语言的所有支持代码, 这是客户端使用模式化数据所需的所有支持代码:DTO, 代理等。强类型语言最终需要此代码, 而鸭子类型(动态)语言则可选。 。
最后但并非最不重要的一点是线路上的数据持久性。最终将实际数据序列化为原始字节(或文本)并反序列化。
所有数据序列化框架都提供了另??一个抽象, 称为协议。协议定义了一组规则, 这些规则定义了如何根据其架构对结构化数据进行序列化或反序列化。通常为给定序列化框架支持的所有编程语言和平台实现每种协议。它支持的编程语言/平台越多, 它应提供的实现就越多。
假设一个框架愿意支持JSON协议, 那么它必须为C#, C ++, Windows, Linux等提供JSON读取器/写入器。
放在一起:任何现代数据序列化框架都可以为你提供以下功能:
  • 抽象:DSL和协议。
  • 代码生成工具。
  • 协议实现。
Microsoft Bond是一个现代的数据序列化框架。它提供了强大的DSL和灵活的协议, 用于C ++和C#的代码生成器, 用于Windows, Linux和Mac OS X的高效协议实现。
多年来, Bond仍然是仅供内部使用的技术, 但是由于Microsoft开源计划的支持, Bond可以在GitHub上使用:Microsoft Bond。
数据序列化竞争对手 软件巨头之间的竞争导致出现了许多序列化框架:
  • Google Inc.-Google协议缓冲区
  • Facebook Inc.-Thrift, 现在由Apache维护
  • Apache Foundation软件-Avro
显然, 它们都是不兼容的, 除非你使用其中之一创建公共API, 否则都可以。
它们每个都有优点和缺点, 因此你可以根据需要从中进行选择。
为什么要Bond? 这个问题的官方答案是:” 为什么要Bond” 。
快速摘要如下:
  • Bond支持丰富的类型系统, 包括泛型。
  • Bond支持模式版本控制和双向兼容性。
  • Bond支持运行时模式操纵。
  • 邦德支持各种集合:” 矢量, 地图, 列表” 。
  • Bond支持类型安全的惰性序列化:” bonded”
  • Bond通过封送处理和转码支持可插拔协议(格式)
一个重要的注意事项是, 邦德遵循” 付费游戏” 策略。添加/使用的功能越多, 你在尺寸和速度上的花费就越多。这为开发人员提供了极大的灵活性。
说实话, 并列出缺点:
  • Bond的目标是支持C ++和C#, 但不支持Java的Microsoft堆栈。
  • Bond不支持联合类型(protobuf中的” oneof” )。
表现如何? 在将一个框架与另一个框架进行比较时, 开发人员经常在寻找性能比较。但请记住, 这些框架由DSL, 代码生成器和协议组成。如果仅考虑协议性能, 那么你将错过DSL和代码生成器提供的功能。有时, 拥有更好的DSL比串行化速度有百分之几的差异更为重要。
除了速度以外, 某些协议支持的节省空间的编码也可能很重要。我建议你对特定于域的数据进行性能/空间比较。这是估计可以从特定框架中获得的所有收益的唯一方法。
Microsoft Bond – 一个新的数据序列化框架

文章图片
本文附带的演示项目通过从Windows应用程序事件日志中读取所有记录, 将它们序列化为Bond对象并反序列化它们, 来演示Bond框架的用法。
要构建和运行演示, 你不需要安装Visual Studio以外的任何软件。
使用Microsoft Bond 得到Bond
查看有关为你的平台获取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, 列表, 向量, 集合, map < K, T> , 可为空” 。
  • 自定义类型的别名和映射, 例如如果你想在C#中使用” DateTime” , 但在线路上打勾(” int64″ )。
  • 定制属性:对于定制代码生成很有用。
无聊?这是一个例子:
namespace MyProjectstruct MyRecord { 0: string Name = "Noname"; 1: vector< double> Constants; }

其中” 0″ 和” 1″ 是字段序号(可以是任意步长的任何整数), 并且=” Noname” 是(可选)默认值。
代码生成
Bond框架提供了用Haskell编写的代码生成工具。以下是在命令行中从” .bond” 模式生成C#和C ++代码的方法:
gbc c# example.bond gbc c++ example.bond

支持的协议(格式)
开箱即用的Bond支持三种协议:
  • 标记的协议:” CompactBinary” 和” FastBinary”
标记的协议在有效载荷内交错模式元数据。这使得有效负载可以自我描述, 即使在不知道生产者使用的模式的情况下, 消费者也可以对其进行解释。
  • 未标记的协议:” SimpleBinary”
未标记的协议仅序列化数据, 因此要求使用者通过某种带外机制了解有效负载方案。未标记协议通常用于存储场景中, 因为它们允许一次存储架构(例如在数据库的系统表中), 从而消除了使用相同架构的许多记录的元数据开销。
  • 基于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);

下一步是什么? 如果你喜欢Bond, 并且有足够的空闲时间来编写代码, 请考虑将其中一项纳入开发范围。我不会列举你可以从贡献中获得的所有好处, 但我知道许多开发人员正在寻找有助于以下方面的想法:
  • 实现Java的端口。你可以选择用其他主流语言替换Java。
  • 实现Bond模式导入/导出以与其他DSL交换(例如” .proto < => .bond” )。
【Microsoft Bond – 一个新的数据序列化框架】无论你决定对邦德做什么, 我建议你首先联系亚当·萨佩克。他是该项目的负责人, 并将为你提供市场最需求的指导。

    推荐阅读