【问题标题】:Spark, Alternative to Fat JarSpark,Fat Jar 的替代品
【发布时间】:2018-02-28 16:36:14
【问题描述】:

我至少知道 2 种方法可以将我的依赖项放入 Spark EMR 作业。一种是创建一个fat jar,另一种是使用--packages 选项指定您希望在spark 中提交的包。

胖罐子需要很长时间才能拉上拉链。这正常吗?约 10 分钟。有没有可能是我们配置不正确?

命令行选项很好,但容易出错。

还有其他选择吗?如果有(已经存在)一种将依赖项列表包含在 gradle 的 jar 中的方法,我会喜欢它,然后让它下载它们。这可能吗?还有其他选择吗?

更新:我发布了部分答案。我在最初的问题中没有明确说明的一件事是,我关心你何时有依赖冲突,因为你有不同版本的同一个 jar。

更新

感谢您对减少依赖项数量或尽可能使用提供的相关回复。为了这个问题,假设我们拥有运行 jar 所需的最少依赖项。

【问题讨论】:

  • 我通常为此使用 SBT。使用sbt-assembly 并利用provided 依赖限定符,您最终可以获得相当合理的胖JAR。你认为你可以分享你的构建文件吗?很难理解为什么没有它们你的胖 JAR 构建需要这么长时间。
  • 你能解释一下你是如何构建你的 jar 的吗?您在使用 AWS Codebuild 吗?你的项目的架构是什么?你的罐子有多大?
  • 我正在使用 gradle 构建我的 jar,并将所有依赖项压缩到其中。

标签: java scala apache-spark gradle amazon-emr


【解决方案1】:

如果必须借助 Spark 启动器通过某些应用程序启动 Spark 作业,则可以使用 Spark 启动器,您可以配置您的 jar patah,无需为运行应用程序创建 fat.jar。

使用 fat-jar 必须安装 Java,启动 Spark 应用程序需要执行 java -jar [your-fat-jar-here]。如果您想从 Web 应用程序启动应用程序,则很难实现自动化。

使用 SparkLauncher,您可以选择从另一个应用程序启动 Spark 应用程序,例如上面的网络应用程序。就简单多了。

import org.apache.spark.launcher.SparkLauncher

SparkLauncher extends App {

val spark = new SparkLauncher()
.setSparkHome("/home/knoldus/spark-1.4.0-bin-hadoop2.6")
.setAppResource("/home/knoldus/spark_launcher-assembly-1.0.jar")
.setMainClass("SparkApp")
.setMaster("local[*]")
.launch();
spark.waitFor();

}

代码: https://github.com/phalodi/Spark-launcher

这里

  • setSparkHome(“/home/knoldus/spark-1.4.0-bin-hadoop2.6”) 用于设置spark home,内部用于调用spark submit。

  • .setAppResource(“/home/knoldus/spark_launcher-assembly-1.0.jar”) 用于指定我们的 spark 应用程序的 jar。

  • .setMainClass(“SparkApp”) spark程序的入口点,即驱动程序。

  • .setMaster(“local[*]”) 在这里设置master的地址,现在我们在本地机器上运行它。

  • .launch() 只是启动我们的 spark 应用程序

What are the benefits of SparkLauncher vs java -jar fat-jar?

https://jaceklaskowski.gitbooks.io/mastering-apache-spark/spark-SparkLauncher.html

https://spark.apache.org/docs/2.0.0/api/java/org/apache/spark/launcher/SparkLauncher.html

http://henningpetersen.com/post/22/running-apache-spark-jobs-from-applications

【讨论】:

    【解决方案2】:

    例如在 Cloudera 的集群上,一些库已经在所有节点上可用,这些库将在驱动程序、执行程序的类路径中可用。 那些是例如spark-core、spark-hive、hadoop 等

    版本按 Cloudera 分组,例如你有 spark-core-cdh5.9.0 其中 cdh5.9.0 后缀意味着所有具有该后缀的库实际上都经过 Cloudera 验证可以正常工作。 您唯一应该做的就是使用具有相同组后缀的库,并且您不应该有任何类路径冲突。

    允许的是: 将应用中配置的依赖项设置为作为 Maven 提供的范围,因此它们不会成为 fat jar 的一部分,而是从节点上的类路径解析。

    你没有写你有什么样的集群,但也许你可以使用类似的方法。

    maven shade插件可用于创建fat jar,它还允许设置你想在jar中包含的库,而不包括那些不在列表中的库。

    我认为这个答案Spark, Alternative to Fat Jar 中描述了类似的东西,但使用 S3 作为依赖存储。

    【讨论】:

      【解决方案3】:

      HubSpot 有一个(部分)解决方案:SlimFast。你可以在这里找到解释http://product.hubspot.com/blog/the-fault-in-our-jars-why-we-stopped-building-fat-jars,你可以在这里找到代码https://github.com/HubSpot/SlimFast

      它有效地将所有需要的 jar 存储在 s3 上,因此在构建时无需打包 jar,但在需要运行时从 s3 获取它们。因此,您的构建速度很快,下载时间也不长。

      我认为如果这也有能力在上传时遮蔽 jar 的路径,以避免冲突,那么这将是一个完美的解决方案。

      【讨论】:

        【解决方案4】:

        胖罐子确实需要很多时间来制作。通过删除运行时不需要的依赖项,我能够进行一些优化。但这真的很痛苦。

        【讨论】:

          猜你喜欢
          • 2016-08-21
          • 1970-01-01
          • 2017-12-12
          • 1970-01-01
          • 2015-08-05
          • 2019-11-22
          • 2017-05-12
          • 2015-04-16
          • 2016-12-26
          相关资源
          最近更新 更多