4.3.3 集成其他开源RPC框架
当前存在非常多的开源RPC框架,比较有名的有Thrift[1], Protocol Buffers[2]和Avro[3]。与Hadoop RPC一样,它们均由两部分组成:对象序列化和远程过程调用。相比于Hadoop RPC,它们有以下几个特点。
❑跨语言特性:前面提到,RPC框架实际上是客户机/服务器模型的一个应用实例。对于Hadoop RPC而言,由于Hadoop采用Java语言编写,因而其RPC客户端和服务器端仅支持Java语言;但对于更通用的RPC框架,如Thrift或者Protocol Buffers等,其客户端和服务器端可采用任何语言编写,如Java, C++,Python等,这给用户编程带来极大的方便。
❑引入IDL:开源RPC框架均提供了一套接口描述语言(Interface Description Language,IDL)。它提供一套通用的数据类型,并以这些数据类型来定义更为复杂的数据类型和对外服务接口。一旦用户按照IDL定义的语法编写完接口文件后,即可根据实际应用需要生成特定的编程语言(如Java, C++,Python等)的客户端和服务器端代码。
❑协议兼容性:开源RPC框架在设计上均考虑到了协议兼容性问题,即当协议格式发生改变时,比如某个类需要添加或者删除一个成员变量(字段)后,旧版本代码仍然能识别新格式的数据,也就是说,具有向后兼容性。
随着Hadoop版本的不断演化,研发人员发现Hadoop RPC在跨语言支持和协议兼容性两个方面存在不足,具体表现为:
1)从长远发展看,Hadoop RPC应允许某些协议的客户端或者服务器端采用其他语言实现,比如用户希望直接使用C/C++语言读写HDFS中的文件,这就需要有C/C++语言的HDFS客户端。
2)当前Hadoop版本较多,而不同版本之间不能通信。比如,0.20.2版本的JobTracker不能与0.21.0版本中的TaskTracker通信,如果用户企图这样做,会抛出VersionMismatch异常。
为了解决以上几个问题,从0.21.0版本开始,Hadoop尝试着将RPC中的序列化部分剥离开,以便将现有的开源RPC框架集成进来。改进之后,Hadoop RPC的类关系如图4-15所示。RPC类变成了一个工厂,它将具体的RPC实现授权给RpcEngine实现类,而现有的开源RPC只要实现RpcEngine接口,便可以集成到Hadoop RPC中。在该图中,WritableRpcEngine是采用Hadoop自带的序列化框架实现的RPC,而AvroRpcEngine[4]和ProtobufRpcEngine[5]分别是开源RPC框架Avro和Protocol Buffers对应的RpcEngine接口实现。用户可通过配置参数rpc.engine.{protocol}以指定协议{protocol}采用的RPC框架。需要注意的是,当前实现中,Hadoop RPC只采用这些开源框架的序列化机制,底层的函数调用机制仍采用Hadoop自带的。
图 4-15 Hadoop RPC集成多种开源RPC框架
在下一代的Hadoop(参见第12章)中,已将Protocol Buffers作为默认的序列化机制[6](而不是Hadoop自带的Writable),这带来的好处主要表现在以下几个方面。
(1)继承了Protocol Buffers的优势
Protocol Buffers已在实践中证明了其高效性,可扩展性,紧凑性和跨语言特性。首先,它允许在保持向后兼容性的前提下修改协议,比如为某个定义好的数据格式添加一个新的字段;其次,它支持多种语言,进而方便用户为某些服务(比如HDFS的NameNode)编写非Java客户端;此外,实验表明Protocol Buffers比Hadoop自带的Writable在性能方面有很大提升。
(2)支持升级回滚
Hadoop 2. 0.0及其以上版本中已经将NameNode HA方案合并进来。在该方案中,NameNode有两种角色:Active和Standby。其中,Active NameNode是当前对外提供服务,而Standby NameNode则能够在Active NameNode出现故障时接替它。采用Protocol Buffers序列化机制后,管理员能够在不停止NameNode对外服务的前提下,通过主备NameNode之间的切换,依次对主备NameNode进行在线升级(不用考虑版本和协议兼容性等问题)。
[1]http://thrift. apache.org/
[2]http://code. google.com/p/protobuf/
[3]http://avro. apache.org/
[4]AvroRpcEngine从Hadoop 0.21.0版本开始出现。
[5]ProtobufRpcEngine从Hadoop 2.0-apha版本开始出现。
[6]https://issues. apache.org/jira/browse/HADOOP-7347