Thrift和协议缓冲区的最大区别?

Apache节俭谷歌的协议缓冲区最大的优点和缺点是什么?

140986 次浏览

协议缓冲区似乎有一个更紧凑的表示,但这只是我从阅读节俭白皮书中得到的印象。用他们自己的话来说:

我们决定反对一些极端的存储优化(即包装 小整数转换成ASCII或使用7位延续格式) 为了代码的简单性和清晰度。这些改变 当我们遇到一个性能关键的问题时,可以很容易地做出什么

此外,这可能只是我的印象,但协议缓冲区似乎有一些更厚的抽象结构版本控制。Thrift确实提供了一些版本控制支持,但是要做到这一点需要付出一些努力。

它们都提供了许多相同的功能;然而,有一些不同之处:

  • 节俭支持“例外”
  • 协议缓冲区有更好的文档/示例
  • Thrift有一个内置的Set类型
  • 协议缓冲区允许“扩展”——你可以扩展一个外部原型来添加额外的字段,同时仍然允许外部代码对这些值进行操作。在节俭中没有办法做到这一点
  • 我发现协议缓冲区更容易阅读

基本上,它们是相当等效的(从我读到的内容来看,协议缓冲区的效率略高)。

  • Protobuf序列化对象大约比Thrift小30%。
  • 你可能想要对protobuf对象做的大多数操作(创建、序列化、反序列化)都是比节俭慢多了,除非你打开option optimize_for = SPEED
  • Thrift具有更丰富的数据结构(Map, Set)
  • Protobuf API看起来更干净,尽管生成的类都打包为内部类,这不是很好。
  • 节俭枚举不是真正的Java枚举,也就是说,它们只是整数。Protobuf有真正的Java枚举。

为了更深入地了解差异,请在这个开源项目中查看源代码差异。

一个尚未提到的明显的事情是,它们既可以是赞成的,也可以是反对的(两者都是一样的),它们是二进制协议。这允许更紧凑的表示和可能更好的性能(优点),但降低了可读性(或更确切地说,可调试性),这是一个缺点。

此外,两者对工具的支持都比xml(甚至json)等标准格式少一些。

(编辑)下面是一个有趣的对比,它处理了大小和amp;性能差异,也包括一些其他格式(xml, json)的数字。

另一个重要的区别是默认支持的语言。

  • 协议缓冲区:Java, Android Java, c++, Python, Ruby, c#, Go, Objective-C, Node.js
  • 节俭:Java、c++、Python、Ruby、c#、Go、Objective-C、JavaScript、Node.js、Erlang、PHP、Perl、Haskell、Smalltalk、OCaml、Delphi、D、Haxe

两者都可以扩展到其他平台,但这些都是现成的语言绑定。

根据维基, Thrift运行时不能在Windows上运行。

RPC是另一个关键区别。Thrift生成代码来实现RPC客户机和服务器,其中协议缓冲区似乎主要被设计为单独的数据交换格式。

与python上的protobuff相比,我能够使用基于文本的协议获得更好的性能。然而,没有类型检查或其他花哨的utf8转换等…这是protobuff提供的。

因此,如果序列化/反序列化是您所需要的,那么您可能可以使用其他方法。

http://dhruvbird.blogspot.com/2010/05/protocol-buffers-vs-http.html

正如我所说的“节俭vs协议缓冲区” topic:

引用Thrift vs Protobuf vs JSON比较:

此外,对于这些解决方案,还有许多有趣的附加工具可用,这可能会决定。下面是Protobuf的例子:Protobuf-wiresharkprotobufeditor

ProtocolBuffers is fast。
这里有一个很好的基准:
https://github.com/eishay/jvm-serializers/wiki(上次更新是2016年,但有一些fork包含更快的序列化器,例如ActiveJ创建了一个fork来演示它们在JVM上的速度:https://github.com/activej/jvm-serializers)

你可能还想看看Avro,它速度更快。在。net中有两个用于Avro的库:

  1. Apache。Avro < / >
  2. 空空的。Avro -由供应链物流公司C.H. Robinson的工程师编写
顺便说一下,我所见过最快的是帽'nProto;
c#实现可以在Marc Gravell的Github-repository.

中找到

我认为大多数观点都忽略了一个基本事实,那就是Thrift是一个RPC框架,它恰好能够使用各种方法(二进制、XML等)序列化数据。

协议缓冲区是纯粹为序列化而设计的,它不像Thrift那样是一个框架。

这里有一些很好的观点,我要再补充一个,以防有人在这里遇到。

Thrift让你可以在Thrift -binary和Thrift -compact(反)序列化器之间进行选择,Thrift -binary将具有出色的性能,但数据包更大,而Thrift -compact将提供良好的压缩,但需要更多的处理能力。这很方便,因为您总是可以在这两种模式之间进行切换,就像更改一行代码一样容易(甚至可以使其可配置)。因此,如果您不确定应用程序在数据包大小或处理能力方面应该优化多少,那么节俭可能是一个有趣的选择。

PS:请看这个由thekvs编写的优秀基准测试项目,它比较了许多序列化器,包括thrift-binary, thrift-compact和protobuf: https://github.com/thekvs/cpp-serializers

PS:还有另一个名为YAS的序列化器也提供了这个选项,但它是无模式的,参见上面的链接。

首先,protobuf并不是一个完整的RPC实现。它需要像gRPC这样的东西来配合。

与Thrift相比,gPRC非常慢:

< a href = " http://szelei。Me /rpc-benchmark-part1/" rel="nofollow noreferrer">http://szelei.me/rpc-benchmark-part1/

同样重要的是要注意,并非所有受支持的语言都与thrift或protobuf一致。在这一点上,除了底层序列化之外,还涉及到模块实现的问题。注意检查您计划使用的语言的基准。

我认为基本的数据结构是不同的

  1. 协议缓冲区使用变长整数,即变长数字编码,将固定长度的数字转换为变长数字以节省空间。
  2. Thrift提出了不同类型的序列化格式(称为“协议”)。 事实上,Thrift有两种不同的JSON编码,以及不少于三种不同的二进制编码方法

总之,这两个库是完全不同的。Thrift喜欢一站式服务,为您提供完整的集成RPC框架和许多选项(支持跨语言),而Protocol Buffers更倾向于“只做一件事并把它做好”。