一、前言
又开始更文了,前面一个多月忙了点别的事情,也给自己放了小假,修整修整,大家应该还没取关我吧,谢谢哈!
这次打算开始一个新的系列,Spark 源码剖析篇,基本上会把 Spark 的各个组件内部核心源码都会讲解一遍;但更文策略有所调整,以前每篇文章3-4000字,写起来周期很长,现在换为短小精悍的风格,这样可以持续输出,动力也会更足,不会因为断更而有挫败感。
嗯,闲聊了几句,进入正题,今天来聊一聊 Spark 的基本通信组件:Spark Rpc。
二、Spark Rpc 的发展
其实工作这么些年头,Spark 用的算比较多,但真正看内部实现比较少,工作上侧重于业务逻辑和调优。Rpc 这部分代码的阅读也是为后面各个组件的源码阅读打好基础,所以这次一定好好看下去!
一个分布式系统必备的基础组件之一,就是分布式通信框架。
Spark 作为一个通用的分布式计算系统,必然存在很多节点之间的通信,它们之间就是使用 RPC (Remote Procedure Call)来进行点对点的通信的。
比如:
- Driver 和 Master 的通信,Driver 会向 Master 发送 RegisterApplication 的消息;
- Master 和 Worker 的通信,Worker 会向 Master 上报 Executor 的信息;
在 Spark 1.6 之前,Spark 的 RPC 是基于 Akka 来实现的。在 Spark 1.6 之后,Spark 借鉴 Akka 的设计自己实现了一个基于 Netty 的 rpc 框架,为什么 Spark 不使用 Akka 了?
主要原因是,很多 Spark 用户自己也使用 Akka,但是不同版本的 Akka 是不能相互通信的,这就要求用户必须使用和 Spark 完全一样的 Akka 版本,导致用户无法升级Akka。
另外,Spark 使用的 Akka 特性本身就比较少,这部分功能完全可以自己实现,有什么问题可以立即 fix,不用等 Akka 官方来修复,所以索性直接放弃 Akka,也是一种解脱。
三、Spark RPC 的主要实现类
1、客户端
客户端的具体实现是 TransportClient,由 TransportClientFactory 创建。
TransportClientFactory 在实例化的时候需要 TransportConf。
TransportClient 创建好了之后,需要通过 TransportClientBootStrap 引导启动。
2、服务端
服务端的具体实现是 TransportServer,创建的时候,需要 TransportContext 中的 TransportConf 和 RpcHandler。
在 init 初始化的时候,由 TransportServerBootstrap 来引导启动
四、总结
今天介绍了 Spark Rpc 的发展历程和主要实现类,下次我们来看看它们的具体实现