对于性能,一个数据点是jvm-serializers基准 - 它是's quite specific, small messages, but might help if you are on Java platform. I think performance in general will often not be the most important difference. Also: NEVER take authors'单词作为福音;许多广告声称是虚假的(例如,msgpack网站有一些可疑的声明;它可能很快,但信息非常粗略,用例不太现实) .
6 回答
ASN.1 是ISO / ISE标准 . 它具有非常易读的源语言和各种后端,包括二进制和人类可读 . 作为一个国际标准(和那个旧的标准!)源语言有点厨房淡化(大致与大西洋有点湿),但是它非常明确,并且具有相当大的支持 . (如果你足够努力,你可以找到你所命名的任何语言的ASN.1库,如果没有,你可以在FFI中使用很好的C语言库 . )它是一种标准化的语言,经过深思熟虑的记录,还提供了一些很好的教程 .
Thrift 不是标准 . 它最初来自Facebook,后来是开源的,目前是一个顶级的Apache项目 . 它没有详细记录 - 特别是教程水平 - 以及我的(不可否认的简短)一瞥已经没有(并且在某些情况下更好) . 为了公平起见,它开箱即用的语言数量相当可观,包括一些较为知名的非主流语言 . IDL也模糊地像C一样 .
Protocol Buffers 不是标准 . 它是一种Google产品,正在向更广泛的社区发布 . 它在开箱即用的语言方面有点受限(它只支持C,Python和Java),但它确实有很多第三方支持其他语言(质量变化很大) . 谷歌使用Protocol Buffers几乎完成了他们所有的工作,所以它是经过实战考验的,经过实战训练的协议(尽管不像ASN.1那样具有战斗力 . 它比Thrift有更好的文档,但是,作为一个谷歌产品,它很可能是不稳定的(在不断变化的意义上,不是不可靠的意义上).IDL也是类似C的 .
所有上述系统都使用在某种IDL中定义的模式来生成目标语言的代码,然后在编码和解码中使用该目标语言 . Avro没有 . Avro的输入是动态的,它的模式数据在运行时直接用于编码和解码(在处理过程中有一些明显的成本,但对动态语言也有一些明显的好处,而且不需要标记类型等) . 它的架构使用JSON,如果已经有一个JSON库,那么在新语言中支持Avro会更容易管理 . 同样,与大多数重新设计车轮的协议描述系统一样,Avro也没有标准化 .
就个人而言,尽管我与它有着爱/恨的关系,但我可能会将ASN.1用于大多数RPC和消息传输目的,虽然它实际上没有RPC堆栈(你必须制作一个,但是IOC会这样做很简单) .
我们刚刚对序列化器进行了内部研究,这里有一些结果(供我将来参考!)
Thrift =序列化RPC堆栈
最大的区别是Thrift不仅仅是一个序列化协议,它就像现代的SOAP堆栈一样 . 因此,在序列化之后,通过TCP / IP在机器之间发送对象 could (但不强制要求) . 在SOAP中,您从一个WSDL文档开始,该文档完整地描述了可用的服务(远程方法)和期望的参数/对象 . 这些对象是通过XML发送的 . 在Thrift中,.thrift文件完整地描述了可用的方法,期望的参数对象和对象通过一个可用的序列化器(使用
Compact Protocol
,一种有效的二进制协议,在 生产环境 中最流行)进行序列化 .ASN.1 =大爸爸
ASN.1是由80年代的电信人员设计的,由于有限的库支持而与CompSci人员出现的最新序列化器相比,使用起来很尴尬 . 有两种变体,DER(二进制)编码和PEM(ascii)编码 . 两者都很快,但DER更快,更有效 . 实际上,ASN.1 DER可以很容易地保持(有时甚至击败)30年后设计的序列化器,这证明它非常紧凑,比协议缓冲器和Thrift小,只能被Avro击败 . 问题在于拥有优秀的图书馆以支持现在的Bouncy Castle似乎是C#/ Java的最佳选择 . ASN.1是安全和加密系统的王者,并且不会担心'future proofing' . 得到一个好的图书馆......
MessagePack =包中间
它并不坏,但它既不是最快的,也不是最小的,也不是最好的支持 . 没有 生产环境 理由选择它 .
普通
除此之外,它们非常相似 . 大多数是基本
TLV: Type-Length-Value
原则的变体 .协议缓冲区(Google发起),Avro(基于Apache,用于Hadoop),Thrift(Facebook发起,现在是Apache项目)和ASN.1(电信发起)都涉及一定程度的代码生成,您首先在序列化程序中表达数据 - 特定格式,然后序列化程序"compiler"将通过
code-gen
阶段为您的语言生成源代码 . 然后,您的应用程序源将这些code-gen
类用于IO . 请注意,某些实现(例如:Microsoft 's Avro library or Marc Gavel' s ProtoBuf.NET)允许您直接装饰您的应用程序级POCO / POJO对象,然后库直接使用那些装饰类而不是任何代码's classes. We' ve看到此提供的提升性能,因为它消除了对象复制阶段(从应用程序级POCO / POJO字段到代码字段) .一些结果和一个现场项目
该项目(https://github.com/sidshetye/SerializersCompare)比较了C#世界中的重要序列化器 . Java人员已经something similar .
关于ASN.1的一个重要的事情是,这是为 specification 而不是实现而设计的 . 因此,它非常擅长隐藏/忽略任何"real"编程语言中的实现细节 .
它的作用是ASN.1-Compiler将编码规则应用于asn1文件并从它们两者生成可执行代码 . 编码规则可以在EnCoding Notation(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-stub-generator,为序列化问题注入了大量空气 . 好吧,如果有人需要,一个人可能没事 . 但对我来说,它们看起来像Sun-RPC的重新设计(从80年代末开始),但是,嘿,这也很好 .
从性能角度来看,优步最近在其工程博客上评估了其中的几个库:
https://eng.uber.com/trip-data-squeeze/
他们的胜利者? MessagePack zlib用于压缩
这里的教训是您的要求驱动哪个库适合您 . 对于优步而言,由于他们拥有的消息传递的无模式特性,他们无法使用基于IDL的协议 . 这消除了一堆选项 . 同样对他们而言,不仅是原始编码/解码时间发挥作用,而且还有静止数据的大小 .
Size Results
Speed Results
微软的Bond(https://github.com/Microsoft/bond)在性能,功能和文档方面令人印象深刻 . 但是,截至目前,它并不支持许多目标平台(2015年3月13日) . 我只能假设它是因为它是非常新的 . 目前它支持python,c#和c . 它被MS无处不在 . 我尝试过,对我来说,使用bond的c#开发人员比使用protobuf更好,但是我也使用了thrift,我遇到的唯一问题是文档,我不得不尝试很多东西来理解事情是如何完成的 .
Bond的资源很少如下(https://news.ycombinator.com/item?id=8866694,https://news.ycombinator.com/item?id=8866848,https://microsoft.github.io/bond/why_bond.html)
对于性能,一个数据点是jvm-serializers基准 - 它是's quite specific, small messages, but might help if you are on Java platform. I think performance in general will often not be the most important difference. Also: NEVER take authors'单词作为福音;许多广告声称是虚假的(例如,msgpack网站有一些可疑的声明;它可能很快,但信息非常粗略,用例不太现实) .
一个很大的区别是是否必须使用模式(PB,至少是Thrift; Avro它可能是可选的; ASN.1我也认为; MsgPack,不一定) .
另外:在我看来,能够使用分层的模块化设计是件好事;也就是说,RPC层不应该规定数据格式,序列化 . 很遗
最后,在选择数据格式时,现在的性能并不排除使用文本格式 . 有快速的JSON解析器(和非常快的流式xml解析器);当考虑脚本语言的互操作性和易用性时,二进制格式和协议可能不是最佳选择 .