我目前正在尝试提交一个spark应用程序,它依赖于几个第三方库(apachetika,…),我想为我的执行器使用一个定制的log4j配置。我在这里浏览了几十个问题是stackoverflow以及spark官方文档,但没有弄清楚我可以预期的确切行为,因此我将尝试在这里总结上下文和我不理解的内容:首先,解释上下文:我在yarn上使用spark 2.3.0,在集群模式(hdp平台)下。
基本上,我第一次尝试
spark-submit --master yarn --deploy-mode=cluster --files ./log4j.properties,./myConfig.properties --class org.company.MyClass --conf 'spark.executor.extraJavaOptions=-Dlog4j.configuration=log4j.properties' ./target/myApplicationUber.jar
第一个问题:和你们中的许多人一样,我面临的问题是依赖冲突:虽然我提供了一个uberjar文件,其中包含了依赖关系中的所有类,但其中一些类已经由hadoop或spark库(较低版本)提供,这在运行时给我的执行者带来了麻烦
作为一种解决方法,我认为我必须为executors类路径预先准备那些依赖项的正确版本,因此我尝试了以下方法:我添加了“-files”选项,专门将库jar文件分发给executors,但意识到这是不够的,因为它们没有添加到类路径中,所以最后尝试了以下命令行:
spark-submit --master yarn --deploy-mode=cluster --files ./log4j.properties,./myConfig.propertie,/absolute/path/to/tika-app.jar,/absolute/path/to/lib2.jar --class org.company.MyClass --conf spark.executor.extraClassPath=tika-app.jar:lib2.jar --conf 'spark.executor.extraJavaOptions=-Dlog4j.configuration=log4j.properties' ./target/myApplicationUber.jar
它工作得很好,只是我意识到tika-app.jar还包括一个“log4j.properties”配置文件,并且它被用来代替我的配置文件。。。
我不明白为什么我用--files选项和我的应用程序uberjar中明确提供的文件没有优先于另一个?
最后,我不得不将文件重命名为mylog4j.properties,并修改命令行以使其正常工作:
spark-submit --master yarn --deploy-mode=cluster --files ./myLog4j.properties,./myConfig.propertie,/absolute/path/to/tika-app.jar,/absolute/path/to/lib2.jar --class org.company.MyClass --conf spark.executor.extraClassPath=tika-app.jar:lib2.jar --conf 'spark.executor.extraJavaOptions=-Dlog4j.configuration=myLog4j.properties' ./target/myApplicationUber.jar
附加问题:
最近,我意识到可以使用--jars选项来分发依赖项jar文件(而不是--files):spark文档声明“…该列表包含在驱动程序和执行器类路径中…”,因此我认为不再需要传递spark.executor.extraclasspath选项,并尝试使用以下命令行:
spark-submit --master yarn --deploy-mode=cluster --files ./myLog4j.properties,./myConfig.properties --jars /absolute/path/to/tika-app.jar,/absolute/path/to/lib2.jar --class org.company.MyClass --conf 'spark.executor.extraJavaOptions=-Dlog4j.configuration=myLog4j.properties' ./target/myApplicationUber.jar
但我回到了第一个依赖性问题(类版本),所以我猜tika-app.jar和lib2.jar还没有添加到我的执行器类路径中。。。
文件有问题吗?还是我在别的地方错了?
最后一个问题:
在解决类路径问题时,我曾多次怀疑spark本身和我的应用程序jar文件之间涉及到什么样的类加载器策略?当jvm在executor中启动时,为什么我在uberjar中提供的所有类和“世界其他地方”之间没有隔离呢?避免同一个库的不同版本之间的冲突不是更容易吗?
感谢那些耐心阅读到最后的人:)
暂无答案!
目前还没有任何答案,快来回答吧!