在前两篇中,咱们经过官网的example体验了livy的功能,留下了一个疑问,究竟livy是如何作到的呢?这一篇从源码里面找一下答案。网络
在直接分析源码前,先把结论经过时序图画出来,有个直观的映像:session
10000~10010
之间的可用端口启动监听,假设此时是10000
。RSCDrvier
。RSCDrvier
首先也从10000~10010
之间顺序选择一个可用的端口,启动RpcServer。图中打出了关键的日志,第二篇中曾经提到过这个日志。RSCDrvier
完成bind后,反向链接到LivyServer端的RpcServer。图中打出了关键的日志,第二篇中一样提到过。RSCDrvier
主要向LivyServer所在的RpcServer上报本身bind的端口和ip。这一步其实就是最关键的步骤。RSCDrvier
的端口和ip封装成ContextInfo
返回给LivyServer。同时关闭RpcServer
。RSCDrvier
的端口和ip链接到RSCDriver,从而完成tcp链接。至此session创建完成以上就是简化的核心工做原理,能够经过netstat
证明一下网络链接关系。vm3198是livyServer,vm3196是driver所在机器tcp
下图是driver上的相关链接:spa
能够看到driver启用了10000端口的监听日志
下图是livyServer上的相关链接:code
能够看到livyServer有一条链接到driver的链路,端口是能够对应上的ip
读者可能注意到,这里Driver的监听端口并非10001,而是10000。这是由于虽然livyServer会率先占用10000,但因为Driver与livyServer不在一台机器上,因此对于Driver来讲,10000当时并无被占用,因此就使用10000端口了
注意到,咱们在livyServer上并无找到10000端口的监听。这是由于,一旦driver将本身的地址回发过来(经过回发RemoteDriverAddress
消息),livyServer的Rpc监听就关闭了。rpc
读者可能会考虑,RSCDrvier
是如何知道livyServer的Rpc监听端点的呢?答案在启动Spark任务时上送的配置文件,咱们摘取其中关键的配置项:get
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通讯的细节有机会还会再基于源码详细展开分析