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


286

Apache ThriftGoogle的Protocol Buffer最大的优缺点是什么?


4
附带说明一下,马克·格拉韦尔(Marc Gravell)维护了一个库,用于与Google的protobuf一起使用,名为protobuf.net,该库位于code.google.com/p/protobuf-net
RCIX

5
这个问题和以下一些答案大约有6年的历史。此后可能发生了很多变化。
AlikElzin-kilaka 2015年

Answers:


159

它们都提供许多相同的功能。但是,有一些区别:

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

基本上,它们是相当等效的(与我所读的协议缓冲区相比,其效率稍高一些)。


16
此演示文稿对它们进行了很好的解释,截至2013年slideshare.net/IgorAnishchenko/pb-vs-thrift-vs-avro
BAR

13
节俭支持的其他10种语言
Elijah Saounkine

1
对于某些语言,您可以添加扩展名。例如,Thrift为C#生成易于扩展的部分类。但是,这不是一般规则,是对的。
JensG

grpc 1.0(proto3)map也支持
KindDragon '16

85

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

  • 协议缓冲区: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

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


16
protobuf具有出色的ruby支持github.com/macks/ruby-protobufcode.google.com/p/ruby-protobuf。我正在使用C#(3.5)和Ruby的protobuf,C#序列化数据,并在需要时使用Ruby反序列化并执行任务。
Bryan Bailliache

6
code.google.com/p/protobuf/wiki/ThirdPartyAddOns列出了PHP,Ruby,Erlang,Perl,Haskell,C#,OCaml以及Actiona脚本,Common Lisp,Go,Lua,Mathlab,Visual Basic,Scala。以为这些都是第三方实现。
伊戈尔·加的斯

您可以在目标c中直接使用protobuf C ++文件(对于iOS和OS X),请检查此qn
Tushar Koul 2013年

我看到code.google.com/p/protobuf-net经常被提及为C#的protobuf端口,但这并不完全正确。Protobuf和Thrift的重要特征之一是外部结构定义,因此相同的定义可以用于不同的语言。protobuf-net不支持此功能,因为它在C#代码中嵌入了结构定义。
Andriy Tylychko 2013年

@AndyT:这值得商--它取决于结构定义是否对所有要支持的语言都是外部的,这是否有利。使用protobuf-net,您可以用C#定义数据结构,并从中生成.proto文件,然后可以使用该文件创建其他语言的支持。我认为这是一个优势,因为我非常以C#为中心,并且正在将Android / Java与大型现有.Net应用程序集成。因此,我想继续将我的C#类视为权威的结构定义。
RenniePet

73

RPC是另一个主要区别。Thrift生成用于实现RPC客户端和服务器的代码,在这些客户端和服务器中,协议缓冲区似乎主要是单独设计为数据交换格式的。


9
这不是真的。协议缓冲区定义了RPC服务api,并且有一些库可用于实现消息传递。
斯蒂芬,2010年

7
我并不是说Protobuf并没有定义RPC,只是它似乎并不是为此而设计的,至少不是每个人都可以访问的外部发行版。在此处
saidimu apale 2010年

9
更重要的是,Thrift内置了RPC支持。Protobuf当前依赖于第三方库,这意味着更少的负担,更少的测试,更不可靠的代码。
亚历克·托马斯

2
对我来说,ProtoBuf很好。如果只需要序列化,则不会添加无用的代码。而且如果将来您需要通过RPC发送它,没问题,它可以工作。我将Netty用于网络,并且Protobuf完全集成在一起,因此没有问题,没有测试,并且可以使性能最大化。
奇奇瓦

14
实际上,Protobuf的设计考虑了RPC。Google刚刚在最近才将该组件开源– grpc.io
andybons 2015年

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

要进一步了解它们之间的差异,请查看此开源项目中的源代码差异。


1
快速建议:如果有另一种非二进制格式(xml或json?)用作基准,那就太好了。尚没有良好的测试来显示总体趋势-假设PB和Thrift的效率更高,但是是否可以提高多少(主要是一个悬而未决的问题)。
StaxMan

4
0.02秒?!我没有多余的时间
克里斯S

1
现在,Thrift具有多个协议(包括TCompactProtocol),我认为第一个项目符号不再适用。
Janus Troelsen '02

13
速度选项的优化现在是协议缓冲区的默认(code.google.com/apis/protocolbuffers/docs/proto.html
威廉

5
是否设置了“ optimize_for = speed”的对象缩小了30%?还是妥协了?
Prashant Sharma

56

正如我所说的“节制与协议缓冲区”主题:

参考Thrift,Protobuf和JSON比较

此外,对于这些解决方案,还有很多有趣的其他工具可以决定。以下是Protobuf的示例:Protobuf-wiresharkprotobufeditor


10
现在,这是一个完整的圈子。您对三个(相似)问题的答案完全相同,并且总是链接回或。我觉得我在玩《塞尔达传说》却错过了征兆。
ChrisR 2015年

+ ChrisR嘿,我不记得是怎么发生的。尽管有几个类似的问题,但也许我应该提出三个类似的结构,而不是循环。有一天,这是一个非常古老的问题,现在我通过电话回复。无论如何,感谢您的追赶!
Grzegorz Wierzowiecki 2015年

6
“节俭带有一个很好的教程”-真有趣。它是我见过的最不完整的教程。一旦您想在TSimpleServer旁边做某事,您就会陷入困境
MarianKlühspies2015年


8

协议缓冲区似乎具有更紧凑的表示形式,但这只是阅读Thrift白皮书给我的印象。用他们自己的话说:

为了简化代码,我们决定不进行某些极端的存储优化(即,将小整数打包为ASCII或使用7位连续格式)。如果遇到性能要求严格的用例,可以轻松进行这些更改。

同样,这可能只是我的印象,但是协议缓冲区似乎在结构版本控制方面有更粗略的抽象。Thrift确实有一些版本控制支持,但是要实现它需要一些努力。


1
为什么Thrift承认没有尽可能的紧凑,这会让您相信协议缓冲区是事实?
Michael Mior

1
协议缓冲区确实使用可变长度整数编码,既用于值又用于字段标识符。因此,发送具有较小值的int字段的最常见情况是两个字节,而不是int16和int32。
12

“协议缓冲区确实使用可变长度整数编码”-TCompactProtocol
也是


7

尚未提及的一件显而易见的事情是,它们既可以是优点,也可以是缺点(并且两者都相同)是它们是二进制协议。这允许更紧凑的表示形式,并可能具有更高的性能(优点),但可读性(或更确切地说,可调试性)却降低了。

而且,两者都比xml(甚至json)等标准格式的工具支持少。

(编辑)这是一个有趣的比较,它解决了大小和性能上的差异,并且还包括其他一些格式(xml,json)的数字。


3
将协议缓冲区输出到比XML更易读的文本表示形式很简单:my_proto.DebugString()。有关示例,请参见code.google.com/apis/protocolbuffers/docs/overview.html
SuperElectric,2011年

当然,所有二进制格式都同上-但这并不能使它们按原样可读(在线调试)。更糟糕的是,对于protobuf,您确实需要架构def才能知道字段名称。
StaxMan 2011年

Thrift支持不同的甚至用户定义的协议。您可以使用二进制,压缩,json或您上周才发明的东西。
JensG

6

并且根据Wiki,Thrift运行时不能在Windows上运行。


5
我在Windows上成功运行Thrift。在github.com/aubonbeurre/thrift上
Sergey Podobry 2011年

20
官方主线分支现在也具有Windows支持。
Janus Troelsen

5
@dalle-Alex P在Thrift中添加了Boost线程支持。现在,它是Windows的默认线程。* NIX默认为pthreads。为了确认Janus T,Thrift现在完全支持Windows。
pmont 2012年

21
这是过时的信息。Thrift现在可以在Windows上完美运行了很长一段时间。
JensG


4

我认为大多数观点都没有想到Thrift是RPC框架这一基本事实,它恰好具有使用多种方法(二进制,XML等)对数据进行序列化的能力。

协议缓冲区是专为序列化而设计的,它不是Thrift之类的框架。


3
您所说的RPC框架是什么意思,它与protobuf的gRPC有什么不同?
marcelocra

gRPC不与protobuf打包在一起。大约十年后才发展起来。Thrift附带完整的RPC框架。它是一起做的。
三部曲


0

这里有一些要点,我还要补充一点,以防有人穿过这里。

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

PS:参见这个出色的基准项目,通过thekvs该项目可以比较许多序列化程序,包括节俭二进制,节俭紧凑和protobuf:https//github.com/thekvs/cpp-serializers

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


0

还需要注意的是,并非所有受支持的语言都能与节俭或protobuf保持一致。在这一点上,除了基础的序列化之外,还取决于模块的实现。请注意检查计划使用的任何语言的基准。

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.