Spark submit deploy_mode cluster 中的第三方JAR包

为什么要使用cluster模式

Spark可以向集群中提交作业,一般生产运营环境我们多建议使用cluster模式向集群提交作业。(和client模式的区别请自行百度)。


理由有四:

1. cluster模式支持 --supervise 参数 

 Spark standalone or Mesos with cluster deploy mode only:

  --supervise                 If given, restarts the driver on failure.


2. client模式往往需要配合nohup等命令才能保证应用在后台运行,比较麻烦。


3. 提交作业的往往都是同一台机器,将所有driver集中到一个节点的做法不是很明智。


4. 大公司往往只开放YARN平台,Driver和Yarn集群如果不在同一个网段,网络通信带来的影响是巨大的,如果Driver也运行在YARN里就好多了。


cluster也有问题


1.提交作业后命令行就返回了,不利用任务的串行调度。如果你的作业集成到了调度中,如工作流、kettle一定要注意这个问题。


2.第二点就是无法添加第三方的Jar包,也就是这篇文章着重解决的问题。



为什么会这样:

我们都知道在提交SPARK作业的时候有很多途径可以提交我们第三方的JAR包:

通过--packages参数,通过--jars参数,定义spark-driver-extraclasspath 以及 spark-excutor-extraclasspath

但是这些在client模式下可以完美的运行,但是一旦迁移到的cluster上就不行了。

原因我在这里赘述,简单来讲就是DRIVER在启动时也需要加载这些JAR包,但是由于cluster模式下DRIVER所在的节点是随机的。

所以他才会抛出class not found的异常。

当然你可以在每个节点上都复制一份你的第三方JAR包,但这并不是一个完美的解决方案。

因为每个JAR包的添加和修改都需要更新整个集群,这个工作量相当大。

事实上我觉得这是一个BUG,我在https://issues.apache.org/jira/browse/SPARK-10789上发现有人反应了同样的问题。

但是社区认为这并不是一个BUG,并且建议我们build一个“assemble jar"

这不失为一种很好的解决方案,即使在client模式下,我认为这也是一种管理第三方JAR包的方案。


怎么解决呢

那么什么是assemble jar呢,简单来说就是把你用到的第三方JAR包也添加到你的作业JAR包中。

比如你用到了KAFKA,那么就把相关kafka的代码copy过来,再打进JAR包,这样就不需要提交作业的时候进行额外添加JAR包了。

至于如何添加,请参考我的另一篇文章 

利用gradle shadow构建包含依赖的JAR包

你可能感兴趣的:(Spark)