flink如何动态支持依赖jar包提交

通常我们在编写一个flink的作业的时候,肯定会有依赖的jar包。flink官方希望你将所有的依赖和业务逻辑打成一个fat jar,这样方便提交,因为flink认为你应该对自己的业务逻辑做好单元测试,而不应该把这部分测试工作频繁提交到集群去做。但事实是我们往往不愿意打一个fat jar,我们希望将业务逻辑独立出来,依赖动态提交。可惜的是,flink并不支持这种提交模式。

flink官方的文档中提供了-C这个选项,来支持提交classpath,我们当时以为这个会有作用,后来再研读源码和实际测试的情况看来,不行,-C不是这么用的。

-C,--classpath , Adds a URL to each user code classloader on all nodes in the cluster. The paths must specify a protocol (e.g. file://) and be accessible on all nodes (e.g. by means of a NFS share). You can use this option multiple times for specifying more than one URL. The protocol must be supported by the {@link

如上,是flink官方文档中对-C的解释,再加上对1.4.2版本源码以及1.5.0版本源码和1.6.0版本源码的研读,以及对cli的实际调用,总结如下:

1.此处的classpath的url必须是一个能够在client,JM和TM都被访问到的位置。

2.此位置从client端的提交到JM的分发到TM的访问的过程中,不会发生文件移动的动作,在1.4.2和1.5.0和1.6.0的版本中都是这样。

3.url支持的协议包括file,ftp,gopher,http,https,jar,mailto,netdoc,亦即java中URL类支持的协议类型。注意:不能放在hdfs上。

所以,如果要想使用-C这个选项,一般有两个做法:

1.手动将classpath中的位置在每个节点上进行部署。

2.使用共享存储,此共享存储可以被所有节点的角色访问。

 

那如何实现我们的要求了?

三个方案:

1.与-yt结合使用

原理:-yt是在yarnCluster模式下用来将本地jar提交到远端的参数,当指定了-yt的值后,客户端会将目录中的jar上传到hdfs中本应用的lib目录中,在tm下载之后,会存在于tm的classpath中。

优点:无需修改代码,结合-yt在创建cluster的时候先行上传依赖文件,在提交作业的时候,再指定-C选项即可。

缺点:

多个作业共享一个cluster,则此cluster需要包含所有的作业可能的依赖。
如果要替换一个依赖,则比较困难,需要重新建立集群
-yt命令虽然将依赖上传到了hdfs,但是-C命令还是需要将文件上传到client端即我们的agent端,操作比较繁杂。


2.改动PackageProgram将lib包放入其library属性中

原理:后续在构建jobGraph的过程中,以library为基准去设置userJar属性。

优点:改动的位置比较靠前,而且packageProgram感觉在将来改动的可能性还是有。

缺点:library是一个用到的地方比较多的属性,是否对其他地方的调用产生影响,需要进一步的研究。

3.改动ClusterClient中的getJobGraph方法,将lib包放入jobGraph的userJar属性中

原理:jobGraph的userJar是用来上传的属性,放入这里,lib包将会被上传到JM的BlobServer中。

优点:比较清晰,改动的影响可控可见,比较没有副作用。

缺点:改动的比较深,对于日后的升级等或许有一定影响。

 

根据我们自己的情况,我们选择了方案2,但在某种情况下,方案1虽然有点烦,但至少不用改源码,也是可以考虑的。

posted @ 2018-08-06 19:58  boiledwater  阅读(4513)  评论(0编辑  收藏  举报