在 Mesos 集群上使用 Spark 时如何预打包外部库

How to pre-package external libraries when using Spark on a Mesos cluster

根据Spark on Mesos docs需要设置spark.executor.uri指向一个Spark分布:

val conf = new SparkConf()
  .setMaster("mesos://HOST:5050")
  .setAppName("My app")
  .set("spark.executor.uri", "<path to spark-1.4.1.tar.gz uploaded above>")

文档还指出,可以构建自定义版本的 Spark 发行版。

我现在的问题是possible/desirable是否要预打包外部库如

这将用于我将通过 spark-submit 提交到

的大部分作业罐

如果可以,如何实现?一般来说,是否有一些提示可以加快作业提交过程中的 fat jar 生成?

背景是我想 运行 为 Spark 作业生成一些代码,并立即提交这些代码并在浏览器前端异步显示结果。前端应该不会太复杂,但是不知道后端是怎么实现的

当您说预打包时,您的意思是分发给所有从属并设置作业以使用这些包,这样您就不需要每次都下载它们了吗?这可能是一个选择,但听起来有点麻烦,因为将所有东西分发给奴隶并保持所有包都是最新的并不是一件容易的事。

如何将您的 .tar.gz 分成更小的部分,以便您的作业获取多个更小的文件而不是单个胖文件?在这种情况下,应该可以利用 Mesos Fetcher Cache。因此,当代理缓存处于冷状态时,您会看到 糟糕 的性能,但一旦它变暖(即一旦一个作业运行并在本地下载公共文件),连续的作业将完成得更快。

是的,您可以将依赖项复制到 workers 并将它们放在系统范围的 jvm lib 目录中,以便将它们放在类路径中。

然后您可以将这些依赖项标记为在您的 sbt 构建中提供,它们将不会包含在程序集中。这确实加快了组装和传输时间。

我没有专门在 mesos 上尝试过这个,但是已经在 spark standalone 上使用它来处理每项工作中很少改变的事情。

使用所有依赖项创建示例 maven 项目,然后使用 maven 插件 maven-shade-plugin。它将在您的目标文件夹中创建一个遮阳罐。

这是示例 pom

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com</groupId>
    <artifactId>test</artifactId>
    <version>0.0.1</version>
    <properties>
        <java.version>1.7</java.version>
        <hadoop.version>2.4.1</hadoop.version>
        <spark.version>1.4.0</spark.version>
        <version.spark-csv_2.10>1.1.0</version.spark-csv_2.10>
        <version.spark-avro_2.10>1.0.0</version.spark-avro_2.10>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <!-- <minimizeJar>true</minimizeJar> -->
                    <filters>
                        <filter>
                            <artifact>*:*</artifact>
                            <excludes>
                                <exclude>META-INF/*.SF</exclude>
                                <exclude>META-INF/*.DSA</exclude>
                                <exclude>META-INF/*.RSA</exclude>
                                <exclude>org/bdbizviz/**</exclude>
                            </excludes>
                        </filter>
                    </filters>
                    <finalName>spark-${project.version}</finalName>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency> <!-- Hadoop dependency -->
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>${hadoop.version}</version>
            <exclusions>
                <exclusion>
                    <artifactId>servlet-api</artifactId>
                    <groupId>javax.servlet</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>guava</artifactId>
                    <groupId>com.google.guava</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.4</version>
        </dependency>

        <dependency> <!-- Spark Core -->
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.10</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency> <!-- Spark SQL -->
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql_2.10</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency> <!-- Spark CSV -->
            <groupId>com.databricks</groupId>
            <artifactId>spark-csv_2.10</artifactId>
            <version>${version.spark-csv_2.10}</version>
        </dependency>
        <dependency> <!-- Spark Avro -->
            <groupId>com.databricks</groupId>
            <artifactId>spark-avro_2.10</artifactId>
            <version>${version.spark-avro_2.10}</version>
        </dependency>
        <dependency> <!-- Spark Hive -->
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-hive_2.10</artifactId>
            <version>${spark.version}</version>
        </dependency>
        <dependency> <!-- Spark Hive thriftserver -->
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-hive-thriftserver_2.10</artifactId>
            <version>${spark.version}</version>
        </dependency>
    </dependencies>
</project>

在我发现 Spark JobServer 项目后,我认为这是最适合我的用例的项目。

它支持通过 REST API 动态创建上下文,以及将 JAR 添加到新创建的上下文 manually/programmatically。它还能够运行低延迟同步作业,这正是我所需要的。

我创建了一个 Dockerfile,因此您可以使用最新(受支持)版本的 Spark (1.4.1)、Spark JobServer (0.6.0) 和内置 Mesos 支持 (0.24.1) 进行试用:

参考文献: