Apache Thrift,Google协议缓冲区,MessagePack,ASN.1和Apache Avro之间的主要区别是什么?


124

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

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



@Zenikoder:该链接没有5种查询格式中的2种信息。
只是我的正确观点,


2
对于不了解RPC的用户-远程Prodecure调用,IDL-接口定义语言
garg10may

Answers:


97

ASN.1是ISO / ISE标准。它具有非常易读的源语言以及各种二进制和人类可读的后端。作为一种国际标准(当时是一种古老的标准!),源语言有点像厨房的味道(与大西洋有点潮湿的方式差不多),但是它的规范非常明确,并且获得了不错的支持。(如果您足够努力地进行挖掘,那么您可能会找到一种针对您所命名的语言的ASN.1库,如果没有,那么您可以在FFI中使用良好的C语言库。)它是一种标准化的语言,具有丰富的文档记录和也有一些很好的教程。

节俭不是标准。它最初来自Facebook,后来开源,目前是Apache的顶级项目。它没有很好的文档记录-尤其是教程级别-而且我的(公认的简短)一眼看上去似乎没有添加其他任何东西,以前的努力没有做过(在某些情况下更好)。公平地说,它具有相当多的开箱即用语言支持,包括一些知名度更高的非主流语言。IDL也模糊地类似于C。

协议缓冲区不是标准。这是一种Google产品,正在向更广泛的社区发布。开箱即用的语言(仅支持C ++,Python和Java)在某种程度上受到限制,但是它确实对其他语言(质量变化很大)提供了很多第三方支持。Google几乎使用协议缓冲区来完成所有工作,因此它是经过考验,经过战斗加固的协议(尽管不像ASN.1那样经过战斗加固。它比Thrift拥有更好的文档,但是, Google产品很可能不稳定(从不断变化的角度来看,而不是从不可靠的角度来看),IDL也类似于C。

以上所有系统均使用以某种IDL定义的架构来生成目标语言的代码,然后将其用于编码和解码。Avro没有。Avro的键入是动态的,其模式数据在运行时直接用于编码和解码(这在处理方面有一些明显的开销,但相对于动态语言也有一些明显的好处,并且不需要标记类型等)。 。它的架构使用JSON,如果已有JSON库,则可以更轻松地管理以新语言支持Avro。再次,与大多数改造车轮的协议描述系统一样,Avro也未标准化。

就我个人而言,尽管我与它之间存在爱恨交织的关系,但我可能还是将ASN.1用于大多数RPC和消息传输目的,尽管它实际上并没有RPC堆栈(您必须创建一个RPC堆栈,但IOC会做到这一点很简单)。


3
感谢您的详细解释。但是关于版本控制呢,我听说protobuf可以解决这个问题,那么关于其他库又如何共同使用呢?此外,似乎Avro除了JSON之外,现在还具有类似C语法的IDL。
andreypopp 2011年

2
ASN.1通过...扩展标记支持手动版本控制,或EXTENSIBILITY IMPLIED在模块标题中自动支持版本控制。协议缓冲区IIRC支持手动版本控制。我不知道它是否支持隐含的可扩展性(而且懒得查找它)。Thrift还支持某些版本控制,但再次以手动过程使我印象深刻,没有隐含的可扩展性。
我的正确观点

7
记录下来,协议缓冲区总是用数字对字段进行显式编码,如果有多余的字段,则在库级别永远不会出错,并且如果将字段标记为可选或显式,则丢失字段也不是错误。因此,所有协议缓冲区消息都具有EXTENSIBILITY IMPLIED
凯文·卡斯卡特

由国际奥委会(IOC)-您的意思是控制权倒置吗?在PHP中,像XML-RPC扩展之类的RPC堆栈将使用什么?还是必须自己写点东西?
斯坦(Stann)

4
Avro更加灵活,因为它允许在定义的架构上动态工作,或者生成样板类。根据我的经验,它非常强大:它的优势在于其丰富的功能集,包括RPC生成器(这是Thrift的常见功能)。
Paolo Maresca 2014年

38

我们刚刚对串行器进行了内部研究,这是一些结果(也供我将来参考!)

节俭=序列化+ RPC堆栈

最大的区别是Thrift不仅是序列化协议,它是一个成熟的RPC堆栈,就像现代的SOAP堆栈一样。因此,在序列化之后,可以(但不要求)通过TCP / IP在计算机之间发送对象。在SOAP中,您从WSDL文档开始,该文档完整描述了可用的服务(远程方法)和预期的参数/对象。这些对象是通过XML发送的。在Thrift中,.thrift文件完整描述了可用的方法,预期的参数对象,并且这些对象通过可用的序列化程序之一进行序列化(使用Compact Protocol有效的二进制协议,在生产中最为流行)。

ASN.1 =大爸爸

ASN.1是由80年代的电信人员设计的,由于与最新的CompSci串行器相比,库支持有限,因此使用起来很尴尬。有两种变体,DER(二进制)编码和PEM(ascii)编码。两者都很快,但是DER的速度更快且尺寸效率更高。实际上,ASN.1 DER可以轻松保持(有时甚至超过)设计了30年的串行器本身就是对精心设计的证明。它非常紧凑,比Protocol Buffer和Thrift小,仅被Avro击败。这个问题需要大量的库来支持,现在Bouncy Castle似乎是C#/ Java的最佳库。ASN.1是安全和加密系统中的王者,并且不会消失,因此不必担心“未来证明”。只要得到一个好的图书馆...

MessagePack =包的中间

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

共同

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

协议缓冲区(起源于Google),Avro(基于Apache,在Hadoop中使用),Thrift(起源于Facebook,现在是Apache项目)和ASN.1(起源于电信)都涉及某种程度的代码生成,您首先需要在序列化器中表达数据特定格式,则序列化程序“编译器”将通过该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
乔·斯蒂尔

它还具有JER — JavaScript对象表示法编码规则。您还可以使用ECN(编码控制符号)定义自己的编码规则。带有下载链接的详细规格列表: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纽约市的2,219个伪随机匿名行程中测试了编码协议和压缩算法组合(以JSON形式输入文本文件)。

这里的教训是,您的需求将决定哪个库适合您。对于Uber,由于它们具有消息传递的无模式性质,因此他们不能使用基于IDL的协议。这消除了很多选择。同样对于他们来说,不仅原始编码/解码时间起作用,而且静止数据的大小也起作用。

尺寸结果

尺寸结果

速度结果

在此处输入图片说明


13

关于ASN.1的一件大事是,ist是为规范 而非实现而设计的。因此,它非常擅长隐藏/忽略任何“真实”编程语言中的实现细节。

ASN.1-Compiler的工作是将编码规则应用于asn1-文件并从二者生成可执行代码。编码规则可能以编码符号(ECN)给出,或者可能是诸如BER / DER,PER,XER / EXER之类的标准化规则之一。即ASN.1是类型和结构,编码规则定义了在线编码,最后但并非最不重要的是编译器将其传输到您的编程语言。

据我所知,免费的编译器支持C,C ++,C#,Java和Erlang。商业编译器(价格昂贵,而且要花费大量专利和许可)非常通用,通常绝对是最新的,并且有时甚至支持更多的语言,但请参见其站点(OSS Nokalva,Marben等)。

使用以下技术来指定完全不同的编程文化的参与者(例如,“嵌入式”人员和“服务器农民”)之间的接口非常容易,这很简单:一个asn.1文件,一个编码规则(例如BER)和一个例如UML交互图。不用担心如何实现,让每个人都使用“他们的东西”!对我来说,它工作得很好。顺便说一句:在OSS Nokalva的站点上,您至少可以找到两本有关ASN.1的免费下载书籍(一本由Larmouth撰写,另一本由Dubuisson撰写)。

恕我直言,其他大多数产品都只是尝试成为另一种RPC存根生成器,这给序列化问题带来了很多麻烦。好吧,如果有人需要的话,那可能很好。但是对我来说,它们看起来像是Sun-RPC的重塑(从80年代后期开始),但是,嘿,那也很好。


7

微软的Bond(https://github.com/Microsoft/bond)在性能,功能和文档方面令人印象深刻。但是,截至目前(2015年2月13日),它不支持许多目标平台。我只能认为这是因为它很新。目前它支持python,c#和c ++。MS到处都在使用它。我尝试过,对我来说,作为使用bond的ac#开发人员比使用protobuf更好,但是我也使用节俭,我面对的唯一问题是文档,我不得不尝试很多事情来理解事情是如何完成的。

是邦德少的资源如下(https://news.ycombinator.com/item?id=8866694https://news.ycombinator.com/item?id=8866848https://microsoft.github.io/ bond / why_bond.html


5

为了提高性能,一个数据点是jvm-serializers基准测试-它是非常具体的小消息,但是如果您使用Java平台,则可能会有所帮助。我认为总体而言,性能通常不会是最重要的区别。另外:永远不要将作者的话当作福音;许多广告宣传是虚假的(例如,msgpack网站上有一些可疑的宣传;它可能很快,但是信息非常粗略,用例不是很现实)。

一个很大的不同是是否必须使用模式(PB,至少是Thrift; Avro它可能是可选的; ASN.1我也认为; MsgPack,不是必须的)。

另外:在我看来,能够使用分层的模块化设计是很好的;也就是说,RPC层不应规定数据格式,序列化。不幸的是,大多数候选人确实把这些捆绑在一起。

最后,在选择数据格式时,当今的性能并不排除使用文本格式。快速的JSON解析器(以及相当快的流式XML解析器)已经到来。考虑到脚本语言的互操作性和易用性,二进制格式和协议可能不是最佳选择。


感谢您的分享经验,但是我认为我仍然需要二进制格式(我的数据量非常大),并且可能会坚持使用Avro。
andreypopp 2011年

是的,那么可能是有道理的。无论使用哪种格式,您都可能希望以任何速率使用压缩(LZF很好,因为与gzip / deflate相比,它的压缩/解压缩速度非常快)。
StaxMan 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.