问题描述:flink程序本地打包成功后上传到flink环境的机器,使用yarn-cluster的方式在hadoop集群上跑。本地程序跑没有问题,在hadoop上报错。
1.背景
任务提交命令:
/data0/flink/flink-1.8.1/bin/flink run -m yarn-cluster -ys 1 -p 2 -yd -ynm jobname -c pkg.mainClass ***.jar
hadop上日志报错如下:
java.lang.NoSuchMethodError: com.google.common.collect.Lists.newCopyOnWriteArrayList()Ljava/util/concurrent/CopyOnWriteArrayList;
因为之前也会遇到类似的问题,大部分情况下都是因为maven中引入的包冲突导致的。
解决方法:排除其他包中因为版本过高或者过低导致的找不到方法或者类。
很明显这个问题不是因为自己pom中的包冲突,而是环境和项目中的包冲突
2.排查
- 使用下面的代码打印出报错的类的在代码运行期间找到的实际的class所在包的位置,确定运行期间使用的class是否是期望的。本地的路径很正常打印的guava18.0的,但是hadoop上打印的如下:/data2/hadoop/local/***/application_1236232/flink-metrics-http-1.81.jar,一个不属于自己项目的jar包路径。应该是hadoop环境开发加进去的一个监控指标的包。
this.getClass().getResource("/com/google/common/collect/Lists.
- 结论:flink任务依赖了第三方的jar,第三方的jar依赖了guava18.0,任务提交到hadoop之后 类加载的时候加载了hadoop环境的低版本的guava
- 解决:flink有个参数 -yt, 这个参数后面配置一个你本地的目录,这个目录存放的是你需要上传到每个 Task ClassPath 下的 jar包。当指定了-yt 值后,客户端会将目录中的jar上传到 hdfs 中本应用的 lib 目录中,在 tm 下载之后,会存在于tm的classpath中。
- 使用方法如下:
./bin/flink run -m yarn-cluster -yt 你的本地目录