Spark源码学习--内置RPC框架(1)

在Spark中很多地方都涉及网络通信,比如Spark各个组件间的消息互通、用户文件与Jar包的上传、节点间的Shuffle过程、Block数据的复制与备份等。在Spark 0.x.x与Spark 1.x.x版本中,组件间的消息通信主要借助于Akka,使用Akka可以轻松地构建强有力的高并发与分布式应用。但是Akka在Spark 2.0.0版本中被移除了,Spark官网文档对此的描述为:“Akka的依赖被移除了,因此用户可以使用任何版本的Akka来编程了。”现在使用的是基于Spark内置RPC框架的NettyStreamManager。节点间的Shuffle过程和Block数据的复制与备份这两个部分在Spark 2.0.0版本中依然沿用了Netty,通过对接口和程序进行重新设计,将各个组件间的消息互通、用户文件与Jar包的上传等内容统一纳入Spark的RPC框架体系中。

我们先来看看RPC框架的基本架构

image.png

TransportContext内部包含传输上下文的配置信息TransportConf和对客户端请求消息进行处理的RpcHandler。TransportConf在创建TransportClientFactory和TransportServer时都是必需的,而RpcHandler只用于创建TransportServer。TransportClientFactory是RPC客户端的工厂类。TransportServer是RPC服务端的实现。图中记号的含义如下。

记号①表示通过调用TransportContext的createClientFactory方法创建传输客户端工厂TransportClientFactory的实例。在构造TransportClientFactory的实例时,还会传递客户端引导程序TransportClientBootstrap的列表。此外,TransportClientFactory内部还存在针对每个Socket地址的连接池ClientPool,这个连接池缓存的定义如下:

private final ConcurrentHashMap connectionPool;

ClientPool的类型定义如下:

private static class ClientPool {
 TransportClient[] clients;
 Object[] locks;

 ClientPool(int size) {
   clients = new TransportClient[size];
   locks = new Object[size];
   for (int i = 0; i < size; i++) {
     locks[i] = new Object();
   }
 }
  }

由此可见,ClientPool实际是由TransportClient的数组构成的,而locks数组中的Object与clients数组中的TransportClient按照数组索引一一对应,通过对每个TransportClient分别采用不同的锁,降低并发情况下线程间对锁的争用,进而减少阻塞,提高并发度。

记号②表示通过调用TransportContext的createServer方法创建传输服务端TransportServer的实例。在构造TransportServer的实例时,需要传递TransportContext、host、port、RpcHandler及服务端引导程序TransportServerBootstrap的列表。

有了对Spark内置RPC框架的基本架构的了解,现在正式介绍Spark的RPC框架所包含的各个组件。
TransportContext:传输上下文,包含了用于创建传输服务端(TransportServer)和传输客户端工厂(TransportClientFactory)的上下文信息,并支持使用Transport-ChannelHandler设置Netty提供的SocketChannel的Pipeline的实现。
TransportConf:传输上下文的配置信息。
RpcHandler:对调用传输客户端(TransportClient)的sendRPC方法发送的消息进行处理的程序。
MessageEncoder:在将消息放入管道前,先对消息内容进行编码,防止管道另一端读取时丢包和解析错误。
MessageDecoder:对从管道中读取的ByteBuf进行解析,防止丢包和解析错误。
TransportFrameDecoder:对从管道中读取的ByteBuf按照数据帧进行解析。
RpcResponseCallback:RpcHandler对请求的消息处理完毕后进行回调的接口。
TransportClientFactory:创建TransportClient的传输客户端工厂类。
ClientPool:在两个对等节点间维护的关于TransportClient的池子。ClientPool是TransportClientFactory的内部组件。
TransportClient:RPC框架的客户端,用于获取预先协商好的流中的连续块。TransportClient旨在允许有效传输大量数据,这些数据将被拆分成几百KB到几MB的块。当TransportClient处理从流中获取的块时,实际的设置是在传输层之外完成的。sendRPC方法能够在客户端和服务端的同一水平线的通信进行这些设置。
TransportClientBootstrap:当服务端响应客户端连接时在客户端执行一次的引导程序。
TransportRequestHandler:用于处理客户端的请求并在写完块数据后返回的处理程序。
TransportResponseHandler:用于处理服务端的响应,并且对发出请求的客户端进行响应的处理程序。
TransportChannelHandler:代理由TransportRequestHandler处理的请求和由Transport-ResponseHandler处理的响应,并加入传输层的处理。
TransportServerBootstrap:当客户端连接到服务端时在服务端执行一次的引导程序。
TransportServer:RPC框架的服务端,提供高效的、低级别的流服务。

                               博客基于《Spark内核设计的艺术:架构设计与实现》一书

  


你可能感兴趣的:(spark,源码学习,大数据)