Apache节俭,Google协议缓冲区,MessagePack,ASN.1和Apache Avro之间的关键区别是什么?

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

所有这些都提供了二进制序列化,RPC框架和IDL。我对它们之间的关键差异和特征(性能,易用性,编程语言支持)感兴趣。

如果您知道其他类似技术,请在答案中提及它。

有帮助吗?

解决方案

ASN.1 是ISO/ISE标准。它具有非常可读的源语言和各种后端,包括二进制和人类可读。作为国际标准(这是一个旧的标准!),源语言有点厨房(与大西洋有点湿的方式相同),但是它非常明确,并且具有相当数量的支持。 (如果您足够努力挖掘,您可能可以找到一个姓名的ASN.1库,并且如果没有良好的C语言库,则可以在FFIS中使用。也有一些好的教程。

节约 不是标准。它最初来自Facebook,后来是开源的,目前是Apache的顶级项目。它没有得到充分记录的文献 - 尤其是教程级别 - 在我的(公认的简短)看来,似乎并没有添加其他任何其他努力尚未做到的东西(在某些情况下更好)。公平地说,它具有相当令人印象深刻的语言,其中包括一些高调的非主流语言。 IDL也模糊地类似于C。

协议缓冲区 不是标准。这是一种被发布给更广泛社区的Google产品。开箱即用的语言(仅支持C ++,Python和Java)有点限制,但是它确实对其他语言(可变质量)有很多第三方支持。 Google使用协议缓冲区几乎完成了他们的所有工作,因此这是一个经过战斗的,战斗的协议(尽管不如ASN.1的战斗力,但它的文档比节俭更好,但是,作为一个Google产品,很可能是不稳定的(从不断变化的意义上讲,不是不可靠的意义)。IDL也类似于C。

以上所有系统都使用在某种IDL中定义的架构来生成目标语言的代码,然后将其用于编码和解码。 Avro没有。 AVRO的键入是动态的,其模式数据在运行时直接使用以编码和解码(在处理方面有一些明显的成本,但对于动态语言而言,一些明显的好处以及缺乏标记类型的需求等)。 。它的模式使用JSON,如果已经有JSON库,则可以使新语言的支持AVRO更容易管理。同样,与大多数车轮更新协议描述系统一样,AVRO也不是标准化。

就我个人而言,尽管我与之的爱/仇恨关系,但我可能会使用ASN.1用于大多数RPC和消息传输目的,尽管它确实没有RPC堆栈(您必须做一个RPC,但是IOC会做到这一点足够简单)。

其他提示

我们刚刚进行了一项关于序列化的内部研究,以下是一些结果(我将来也参考!)

节俭=序列化 + RPC堆栈

最大的区别是,节俭不仅是序列化协议,而且是一个完整的RPC堆栈,就像现代的肥皂堆一样。因此,在序列化之后,对象 可以 (但未规定)通过TCP/IP之间的机器之间发送。在SOAP中,您从一个WSDL文档开始,该文档充分描述了可用的服务(远程方法)和预期的参数/对象。这些对象是通过XML发送的。在节俭中,.thift文件充分描述可用方法,预期参数对象和对象是通过可用序列化的一个序列化的(带有 Compact Protocol, ,一种有效的二进制协议,在生产中最受欢迎)。

asn.1 =大爸爸

ASN.1是由80年代电信人员设计的,是 尴尬的 与COMPSCI人出现的最新序列化相比,由于库支持有限而使用。有两个变体,DER(二进制)编码和PEM(ASCII)编码。两者都是快速的,但是DER的速度更快,大小的效率更高。实际上,ASN.1 der可以轻松地跟上设计的连续序列化(有时是击败) 30年 毕竟,这是其设计精良的设计。它非常紧凑,小于协议缓冲区和节俭,只被Avro击败。问题是拥有很棒的图书馆来支持,现在有弹性城堡似乎是C#/Java的最佳图书馆。 ASN.1是安全和加密系统的国王,不会消失,因此不要担心“未来的证明”。只要得到一个好的图书馆...

MessagePack =包装中间

这还不错,但既不是最快,也不是最小的,也不是最好的支持。没有生产理由选择它。

常见的

除此之外,它们还很相似。大多数是基本的变体 TLV: Type-Length-Value 原则。

协议缓冲区(Google ointed),AVRO(基于Apache,在Hadoop中使用),Thrift(Facebook发起,现在是Apache Project)和ASN.1(Telecom Ounted)都涉及一定级别的代码生成,您首先在序列化器中表达数据 - 特定格式,然后序列化器“编译器”将通过该语言生成源代码 code-gen 阶段。然后您的应用程序来源使用这些 code-gen IO课程。请注意,某些实现(例如:Microsoft的AVRO库或Marc Gavel的Protobuf.net)让您直接装饰应用程序级别POCO/POJO对象,然后该库直接使用这些装饰的类而不是任何代码 - 基因的类。我们已经看到了这一提升性能,因为它消除了对象复制阶段(从应用程序级别的POCO/POJO字段到Code-Gen字段)。

一些结果和一个现场项目可以玩

这个项目 (https://github.com/sidshetye/serializerscompare)比较C#世界中的重要连续剧。爪哇人已经有 相似的东西.

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/

他们的获胜者? MessagePack + Zlib用于压缩

我们的目标是在最高速度下找到编码协议和压缩算法与最紧凑的结果的组合。我们测试了从Uber New York City的2,219个伪和匿名旅行进行编码协议和压缩算法组合(将文本文件放入JSON)。

这里的教训是,您的要求驱动器适合您的库。对于Uber,由于他们拥有的消息传递的示意性质,他们无法使用基于IDL的协议。这消除了很多选择。同样,对于他们来说,不仅是原始的编码/解码时间,还可以在静止时进行数据大小。

尺寸结果

Size Results

速度结果

enter image description here

关于ASN.1的一件大事是,IST是为 规格 不是 执行。因此,在任何“真实”编程语言中隐藏/忽略实施细节非常擅长。

它是ASN.1编译器的工作,将编码规则应用于ASN1文件并从两个可执行代码中生成。编码规则可以在编码符号(ECN)中给出,也可以是标准化规则,例如BER/DER,PER,XER/EXER。那就是ASN.1是类型和结构,编码规则定义了电线编码上的规则,最后但并非最重要的是编译器将其传输到您的编程语言。

自由编译器支持C,C ++,C#,Java和Erlang,据我所知。 (到昂贵和专利/许可证)的商业编译器非常广泛,通常是绝对最新的,有时甚至更多的语言支持,但请参阅其网站(OSS Nokalva,Marben等)。

使用此技术来指定完全不同的编程文化(例如“嵌入者和“服务器农民”)之间的界面:ASN.1文件,编码规则,例如,EG UML互动图,这是非常容易的。不用担心它的实施方式,让每个人都使用“他们的东西”!对我来说,它运行良好。顺便说一句:在Oss Nokalva的网站上,您可能至少发现两本关于ASN.1的免费书籍(一本由Larmouth由Dubuisson撰写的Larmouth)。

恕我直言,其他大多数产品都只是尝试成为迄今为止的RPC-stub发电机,将大量空气泵入序列化问题。好吧,如果需要的话,可能会没事的。但是对我来说,它们看起来像是Sun-RPC的重塑(从80年代后期),但是,嘿,这也很好。

微软的债券(https://github.com/microsoft/bond)对性能,功能和文档非常令人印象深刻。但是,到目前为止,它不支持许多目标平台(2015年2月13日)。我只能假设是因为它非常新。目前,它支持Python,C#和C ++。到处都是MS。我尝试了一下,因为使用债券的AC#开发人员比使用Protobuf更好,但是我也使用了节俭,我遇到的唯一问题是在文档中,我不得不尝试很多事情来了解如何完成事情。

债券上的资源很少如下( https://news.ycombinator.com/item?id=8866694 , https://news.ycombinator.com/item?id=8866848 , https://microsoft.github.io/bond/why_bond.html )

为了性能,一个数据点是 JVM-Serializer 基准 - 这是非常具体的小消息,但是如果您在Java平台上,可能会有所帮助。我认为总体表现通常不是最重要的区别。另外:切勿以作者的话为福音;许多广告宣传的说法是伪造的(例如,MSGPACK网站有一些可疑的主张;它可能很快,但是信息非常粗略,用例不是很现实)。

一个很大的区别是是否必须使用架构(PB,至少节俭; Avro可能是可选的; ASN.1我也认为; MSGPACK,不一定是)。

另外:我认为能够使用分层的模块化设计是一件好事。也就是说,RPC层不应决定数据格式,序列化。不幸的是,大多数候选人都会紧紧捆绑这些。

Finally, when choosing data format, nowadays performance does not preclude use of textual formats.有燃烧的快速JSON解析器(以及相当快的流XML解析器);当考虑脚本语言的互操作性和易用性时,二进制格式和协议可能不是最佳选择。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top