What are the biggest pros and cons of Apache Thrift vs Google's Protocol Buffers?
15 回答
They both offer many of the same features; however, there are some differences:
- Thrift supports 'exceptions'
- Protocol Buffers have much better documentation/examples
- Thrift has a builtin
Set
type - Protocol Buffers allow "extensions" - you can extend an external proto to add extra fields, while still allowing external code to operate on the values. There is no way to do this in Thrift
- I find Protocol Buffers much easier to read
Basically, they are fairly equivalent (with Protocol Buffers slightly more efficient from what I have read).
另一个重要的区别是默认支持的语言。
- 协议缓冲区:Java、Android Java、C++、Python、Ruby、C#、Go、Objective-C、Node.js
- Thrift:Java、C++、Python、Ruby、C#、Go、Objective-C、JavaScript、Node.js、Erlang、PHP、Perl、Haskell、Smalltalk、OCaml、Delphi、D、Haxe
两者都可以扩展到其他平台,但这些是开箱即用的语言绑定。
RPC 是另一个关键区别。Thrift 生成代码来实现 RPC 客户端和服务器,其中 Protocol Buffers 似乎主要设计为单独的数据交换格式。
- Protobuf 序列化对象比 Thrift 小 30% 左右。
- 除非您打开
option optimize_for = SPEED
. - Thrift 拥有更丰富的数据结构(Map、Set)
- Protobuf API 看起来更干净,虽然生成的类都被打包为内部类,这不是很好。
- Thrift 枚举不是真正的 Java 枚举,即它们只是整数。Protobuf 有真正的 Java 枚举。
要仔细查看差异,请查看此开源项目的源代码差异。
正如我所说的“节俭与协议缓冲区”主题:
参考Thrift vs Protobuf vs JSON 比较:
- Thrift 支持开箱即用的AS3、C++、C#、D、Delphi、Go、Graphviz、Haxe、Haskell、Java、Javascript、Node.js、OCaml、Smalltalk、Typescript、Perl、PHP、Python、Ruby...
- C++、Python、Java - Protobuf 中的内置支持
- Protobuf 支持其他语言(包括 Lua、Matlab、Ruby、Perl、R、Php、OCaml、Mercury、Erlang、Go、D、Lisp)作为第三方插件提供(顺便说一句。这里是 SWI-Prolog 支持)。
- Protobuf 有更好的文档和大量的示例。
- Thrift 附带了一个很好的教程
- Protobuf 对象更小
- 使用“optimize_for = SPEED”配置时,Protobuf 更快
- Thrift 集成了 RPC 实现,而对于Protobuf RPC 解决方案是分离的,但可用(如Zeroc ICE)。
- Protobuf 在 BSD 风格的许可下发布
- Thrift 在 Apache 2 许可下发布
此外,还有许多有趣的附加工具可用于这些解决方案,这可能会有所决定。以下是 Protobuf 的示例:Protobuf-wireshark,protobufeditor。
Protocol Buffers seems to have a more compact representation, but that's only an impression I get from reading the Thrift whitepaper. In their own words:
We decided against some extreme storage optimizations (i.e. packing small integers into ASCII or using a 7-bit continuation format) for the sake of simplicity and clarity in the code. These alterations can easily be made if and when we encounter a performance-critical use case that demands them.
Also, it may just be my impression, but Protocol Buffers seems to have some thicker abstractions around struct versioning. Thrift does have some versioning support, but it takes a bit of effort to make it happen.
与 python 上的 protobuff 相比,我能够使用基于文本的协议获得更好的性能。但是,protobuff 没有提供类型检查或其他花哨的 utf8 转换等。
因此,如果您只需要序列化/反序列化,那么您可能可以使用其他东西。
http://dhruvbird.blogspot.com/2010/05/protocol-buffers-vs-http.html
尚未提及的一件显而易见的事情是,它们既可以是赞成也可以是反对(并且两者都相同)是它们是二进制协议。这允许更紧凑的表示和可能更高的性能(优点),但降低了可读性(或者更确切地说,可调试性),这是一个缺点。
此外,两者的工具支持都比 xml(甚至可能是 json)等标准格式少一些。
(编辑)这是一个有趣的比较,它解决了大小和性能差异,还包括一些其他格式(xml、json)的数字。
ProtocolBuffers 更快。
这里有一个很好的基准:
http ://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking
您可能还想研究 Avro,因为 Avro 更快。
微软在这里有一个包:
http ://www.nuget.org/packages/Microsoft.Hadoop.Avro
顺便说一句,我见过的最快的是Cap'nProto;
AC# 实现可以在Marc Gravell 的 Github-repository 中找到。
根据wiki,Thrift 运行时不能在 Windows 上运行。
我认为这些观点中的大多数都忽略了 Thrift 是一个 RPC 框架的基本事实,它恰好具有使用各种方法(二进制、XML 等)序列化数据的能力。
Protocol Buffers 纯粹是为序列化而设计的,它不是像 Thrift 这样的框架。
我认为基本数据结构不同
- Protocol Buffer 使用变长整数,即变长数字编码,将固定长度的数字变成可变长度的数字以节省空间。
- Thrift 提出了不同类型的序列化格式(称为“协议”)。事实上,Thrift 有两种不同的 JSON 编码,以及不少于三种不同的二进制编码方式。
总之,这两个库是完全不同的。Thrift 喜欢一站式服务,给你整个集成的 RPC 框架和很多选项(支持跨语言),而 Protocol Buffers 更倾向于“只做一件事,把它做好”。
一方面,protobuf 不是一个完整的 RPC 实现。它需要像 gRPC 这样的东西来配合它。
gPRC 与 Thrift 相比非常慢:
这里有一些很好的点,我将添加另一个点,以防有人的路径在这里交叉。
Thrift 为您提供了在 thrift-binary 和 thrift-compact (de)serializer 之间进行选择的选项,thrift-binary 将具有出色的性能但更大的数据包大小,而 thrift-compact 将为您提供良好的压缩但需要更多的处理能力。这很方便,因为您总是可以像更改一行代码一样轻松地在这两种模式之间切换(哎呀,甚至可以使其可配置)。因此,如果您不确定您的应用程序应该针对数据包大小或处理能力优化多少,那么 Thrift 可能是一个有趣的选择。
PS:查看这个优秀的基准项目,thekvs
它比较了许多序列化程序,包括 thrift-binary、thrift-compact 和 protobuf:https ://github.com/thekvs/cpp-serializers
PS:还有另一个名为的序列化程序YAS
也提供了此选项,但它是无模式的,请参见上面的链接。
还需要注意的是,并非所有受支持的语言都与 thrift 或 protobuf 一致。在这一点上,除了底层序列化之外,还有模块实现的问题。请注意检查您计划使用的任何语言的基准。