Spark 笔记|教程 —— 如何使用spark-submit

我们用IDE或者Jupyter等在本地(local mode)运行测试代码非常方便,但是在实际应用中,由于数据量比较大,运行时间长,往往使用cluster mode,而且需要在Linux系统后台运行应用(比如用Screen),或者在server中自动或者定时运行应用(比如用Cron)。这就需要使用bin/spark-submit提交我们的的application,启动driver program。然后driver program联系cluster manager去启动executors,然后driver发送任务给executors,由executors运行任务并存储数据。

对于Scala和Java来说可以把代码打包成jar文件,对于Python来说可以直接提交一个或多个.py文件或者.zip文件(使用--py-files)。

我使用的是Gradle build tool,和Maven相当,不需要特别的安装,可以对单个项目来使用。对于Scala和Java应用,使用Intellij会非常简单。

在Intellij创建一个Gradle项目,如下图

选好SDK后点Next,然后GroupId本地应用可以省略,ArtifactId可以是自己的项目名称,然后点Next。

后面就是设置自己的项目路径,其他默认就好,然后点Finish。

然后在IDEA目录中打开build.gradle文件,填写或者补充好下面配置

group 'Spark_gradle'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'idea'

sourceCompatibility = 1.8

idea {
    project {
        jdkName = '1.8'
        languageLevel = '1.8'
    }
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
}

repositories {
    mavenCentral()
}

dependencies {
    compile group: 'org.apache.spark', name: 'spark-core_2.11', version: '2.2.0'
    compile group: 'org.apache.spark', name: 'spark-sql_2.11', version: '2.1.1'
    compile group: 'org.tensorflow', name: 'tensorflow', version: '1.4.0'
}


jar {
    zip64 true
    archiveName = "test.jar"
    from {
        configurations.compile.collect {
            it.isDirectory() ? it : zipTree(it)
        }
    }
    manifest {
        attributes 'Main-Class': 'Main'
    }

    exclude 'META-INF/*.RSA', 'META-INF/*.SF','META-INF/*.DSA'

}

上面配置中第一行是你的GroupId,会有不同。添加apply plugin: 'idea'是为了是IDEA之后可以用open project打开你的项目,对产生jar文件没有影响,可以省略。最重要的是添加好你的dependencies,这个和Maven的使用方法一样。

最后就是配置你打包的jar文件的信息archiveName是最后jar文件的名字,manifest/attributes是执行你程序的Main文件的路径,这个路径是在src文件里的路径。通常是/packageName/path/to/Main

使用Gradle build tool的好处就是只要写好了dependencies,所有的library都会打包在一个jar文件中,然后直接submit这个jar文件就行了。

配置好build.gradle后,从terminal/command line进入你的spark java/scala项目的根目录,运行

./gradlew jar

Gradle会自动在这个项目的build/libs目录下生成你的jar文件。之后把这个文件移动到$SPARK_HOME的上一级文件夹中,即与spark文件夹处于同一目录。然后在这个文件夹创建一个子文件夹,存放数据,我这里叫in。我的文件结构如下:

-/usr/local
 - in
 - spark2.2
 - example.jar

然后在local目录运行下面命令就行了

./spark2.2/bin/spark-submit example.jar

运行spark-submit时还可以添加许多控制信息,如master地址

$ ./bin/spark-submit
Usage: spark-submit [options]  [app arguments]
Usage: spark-submit --kill [submission ID] --master [spark://...]
Usage: spark-submit --status [submission ID] --master [spark://...]
Usage: spark-submit run-example [options] example-class [example args]
...

上面的[options]可以是控制每个executor使用机器资源的信息

./bin/spark-submit \
    --executor-memory 10G \
    --total-executor-cores 4 \
    /path/to/examples.jar

具体的options说明可以参照官网,这里

登录注册后参与评论