通常我们在编写一个flink的作业的时候,肯定会有依赖的jar包。
flink官方希望你将所有的依赖和业务逻辑打成一个fat jar,这样方便提交,因为flink认为你应该对自己的业务逻辑做好单元测试,而不应该把这部分测试工作频繁提交到集群去做。
但事实是我们往往不愿意打一个fat jar,我们希望将业务逻辑独立出来,依赖动态提交。
可惜的是,flink并不支持这种提交模式。
flink官方的文档中提供了-C这个选项,来支持提交classpath,我们当时以为这个会有作用,后来再研读源码和实际测试的情况看来,不行,-C不是这么用的。
https://ci.apache.org/projects/flink/flink-docs-release-1.7/ops/cli.html
如上,是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虽然有点烦,但至少不用改源码,也是可以考虑的。
https://www.cnblogs.com/029zz010buct/p/9432264.html