RPC, Serialization and Schema

The post is brought to you by lekhonee v0.7

糖果项目的后端用Java编写,我负责service gateway的开发(暂且叫sergent),服务以Java接口+Annotation的形式声明,与Spring集成使用,Java对象被序列化为JSON和XML(通过jackson和castor)与外部系统交互。专门的JSON Schema和XML Schema是可选的,系统交互通过简明的文档和人工确认。

RPC框架是跨进程、跨系统交互的重要工具,RPC框架中又包括远程调用、网络传输和序列化反序列化等等部分。流行的工具包括Facebook的thrift,Google的Protobuf和原先Hadoop项目下的avro。其中thrift包含远程调用、反序列化、网络等等全部的功能。Protobuf本身是一个序列化反序列化库,另有很多第三方RPC实现,avro目前除了序列化和反序列化的功能,也包含了ipc的HTTP Server和SocketServer等实现。在序列化的格式方面,Thrift支持JSON和二进制协议,Protobuf本身仅有二进制支持,但已经存在第三方的其他格式实现。 avro原生支持二进制和JSON格式。

从效率上来说,二进制方式的序列化要比文本方式的快。Google Code上(最近迁往了github)有一个tpc项目(thrift-protobuf-compare),根据这个项目的最新的比较结果(与原先不同):

protobuf成为了三者中耗时最少的框架,之后是thrift和avro,这次avro的耗时甚至超过了文本方式的jackson(主要在反序列化上)。

但是二进制协议通常都需要定义Schema,thrift / protobuf / avro三者各自定义了Schema的格式,没有类似XSD和Json Schema的统一标准,也就是说,当你需要传输一个对象,就要为它编写一个Schema文件。按照通常的习惯,都是先编写Schema,然后通过命令行工具或者自动构建工具来生成Java source。对于新系统还好说,对旧系统这个改造就比较麻烦了。另外,二进制协议不便于调试,所以各个thrift/protobuf/avro先后也都有JSON的实现,在文本的序列化格式上,JSON对XML的优势是全方位的。

所以综合起来,很难说有一种完美的解决方案。二进制协议的效率高,但是改造、编写Schema的代价并不小,还要面对核心Model被绑架到具体框架的风险。文本协议开发简便,不需要Schema,直接POJO就可以序列化和反序列化,但是在时间和空间上都不如二进制的方式。

补充
从tpc项目的结果上看,kryo在时间、空间上都击败了所有对手,而且,kryo的API非常简洁,不需要Schema文件就可以序列化POJO,听起来太完美了,看来以后sergent要借鉴一下的。

补充 2010-06-14
发现avro现在也有ReflectDatumReader和ReflectDatumWriter,可以通过反射内部自动映射生成Schema,可以尝试一下。

8 thoughts on “RPC, Serialization and Schema

  1. 我是倾向于protobuf那种要有schema的观念的,因为强类型会给几乎所有层次带来好处。
    实际上我觉得序列化的所有结果中都加入类型元数据都不为过,毕竟这部分信息相对于整体数据还是相当小的。而且利用类型信息还能避免解析对象的嵌套结构,性能也会有很大提升。比如{”a”:{“b”:{“c”:4.12}},”d”:”qqqq”}这样的数据,再复杂一些解析效率和容错率会很低。但如果有类型信息,就可以合并为a-b-c:4.12,d:”qqqq”这样的单一层次。

    我看过最舒适的RPC接口设计还是GWT RPC的设计:纯接口、Serializable即可作为参数或异常,annotation的作用也恰到好处,异步接口也是所见即所得。

  2. 不过话说回来,RPC作为系统交互的范式是有抽象泄漏的问题的。过去的一些RPC框架甚至不支持异常处理,这个问题就更严重。现在在网络遇到一些问题的时候,RPC范式也往往必须暴露一些实现细节才能方便的维护。

    从这个角度看,可能老实的消息总线范式倒是更合适。比如像linux底层的dbus那样,区分方法调用、方法返回、信号和错误四种消息,然后使用消息匹配器和接口来管理服务调用,可能一开始稍复杂一些,但很皮实,不容易出问题。

    • 说实在的我就看中这里的这个,也算是比较幸运分给我基础设施,我周围大部分也都是做业务的同事,每天被产品折腾得不行,改来改去。

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>