在前两篇中,咱们通过官网的 example 体验了 livy 的性能,留下了一个疑难,到底 livy 是如何做到的呢?这一篇从源码外面找一下答案。
在间接剖析源码前,先把论断通过时序图画进去,有个直观的映像:
- 客户端创立 session,LivyServer 收到申请后启动一个 RpcServer。RpcServer 会程序抉择一个从
10000~10010
之间的可用端口启动监听,假如此时是10000
。 - LivyServer 随后通过 SparkSubimit 提交 Application。Application 在远端,最终会启动
RSCDrvier
。 RSCDrvier
首先也从10000~10010
之间程序抉择一个可用的端口,启动 RpcServer。图中打出了要害的日志,第二篇中已经提到过这个日志。RSCDrvier
实现 bind 后,反向连贯到 LivyServer 端的 RpcServer。图中打出了要害的日志,第二篇中同样提到过。RSCDrvier
次要向 LivyServer 所在的 RpcServer 上报本人 bind 的端口和 ip。这一步其实就是最要害的步骤。- RpcServer 收到申请后将
RSCDrvier
的端口和 ip 封装成ContextInfo
返回给 LivyServer。同时敞开 RpcServer
。 - LivyServer 通过
RSCDrvier
的端口和 ip 连贯到 RSCDriver,从而实现 tcp 连贯。至此 session 建设实现
以上就是简化的外围工作原理,能够通过 netstat
证实一下网络连接关系。vm3198 是 livyServer,vm3196 是 driver 所在机器
下图是 driver 上的相干连贯:
能够看到 driver 启用了 10000 端口的监听
下图是 livyServer 上的相干连贯:
能够看到 livyServer 有一条连贯到 driver 的链路,端口是能够对应上的
读者可能留神到,这里 Driver 的监听端口并不是 10001,而是 10000。这是因为尽管 livyServer 会率先占用 10000,但因为 Driver 与 livyServer 不在一台机器上,所以对于 Driver 来说,10000 过后并没有被占用,所以就应用 10000 端口了
留神到,咱们在 livyServer 上并没有找到 10000 端口的监听。这是因为,一旦 driver 将本人的地址回发过来(通过回发 RemoteDriverAddress
音讯),livyServer 的 Rpc 监听就敞开了。
读者可能会思考,RSCDrvier
是如何晓得 livyServer 的 Rpc 监听端点的呢?答案在启动 Spark 工作时上送的配置文件,咱们摘取其中要害的配置项:
spark.__livy__.livy.rsc.launcher.address=vm3198
spark.__livy__.livy.rsc.launcher.port=10000
launcher.address/port;就是 livyServer 启动的 Rpc 监听端点。从 RSCDriver 的源码能够看到,程序从配置文件中读取了信息:
...
// Address for the RSC driver to connect back with it's connection info.
LAUNCHER_ADDRESS("launcher.address", null)
LAUNCHER_PORT("launcher.port", -1)
...
String launcherAddress = livyConf.get(LAUNCHER_ADDRESS);
int launcherPort = livyConf.getInt(LAUNCHER_PORT);
...
LOG.info("Connecting to: {}:{}", launcherAddress, launcherPort);
总结
本篇咱们探索了 livy 的外围工作机制,理解了建设 session 时,在 livyServer 和 Driver 之间是如何建设连贯关系的。更多对于 rpc 通信的细节有机会还会再基于源码具体开展剖析