在Java应用中通过SparkLauncher启动Spark任务
本博客内容基于Spark2.2版本,在阅读文章并想实际操作前,请确保你有:
- 一台配置好Spark和yarn的服务器
- 支持正常
spark-submit --master yarn xxxx
的任务提交
老版本
老版本任务提交是基于启动本地进程,执行脚本spark-submit xxx
** 的方式做的。其中一个关键的问题就是获得提交Spark任务的Application-id,因为这个id是跟任务状态的跟踪有关系的。如果你的资源管理框架用的是yarn,应该知道每个运行的任务都有一个applicaiton_id,这个id的生成规则是:
appplication_时间戳_数字
老版本的spark通过修改SparkConf参数spark.app.id
就可以手动指定id,新版本的代码是直接读取的taskBackend中的applicationId()方法,这个方法具体的实现是根据实现类来定的。在yarn中,是通过Yarn的YarnClusterSchedulerBackend实现的。
感兴趣的同学可以看一下,生成applicaiton_id的逻辑在hadoop-yarn工程的ContainerId中定义。
总结一句话就是,想要自定义id,甭想了!!!!
于是当时脑袋瓜不灵光的我,就想到那就等应用创建好了之后,直接写到数据库里面呗。怎么写呢?
- 我事先生成一个自定义的id,当做参数传递到spark应用里面;
- 等spark初始化后,就可以通过sparkContext取得对应的application_id以及url
- 然后再driver连接数据库,插入一条关联关系
新版本
还是归结于互联网时代的信息大爆炸,我看到群友的聊天,知道了SparkLauncer这个东西,调查后发现他可以基于Java代码自动提交Spark任务。SparkLauncher支持两种模式:
- new SparkLauncher().launch() 直接启动一个Process,效果跟以前一样
- new SparkLauncher().startApplicaiton(监听器) 返回一个SparkAppHandler,并(可选)传入一个监听器
当然是更倾向于第二种啦,因为好处很多:
- 自带输出重定向(Output,Error都有,支持写到文件里面),超级爽的功能
- 可以自定义监听器,当信息或者状态变更时,都能进行操作(对我没啥用)
- 返回的SparkAppHandler支持 暂停、停止、断连、获得AppId、获得State等多种功能,我就想要这个!!!!
一步一步,代码展示
首先创建一个最基本的Spark程序:
import org.apache.spark.sql.SparkSession;
import java.util.ArrayList;
import java.util.List; public class HelloWorld {
public static void main(String[] args) throws InterruptedException {
SparkSession spark = SparkSession
.builder()
//.master("yarn")
//.appName("hello-wrold")
//.config("spark.some.config.option", "some-value")
.getOrCreate(); List<Person> persons = new ArrayList<>(); persons.add(new Person("zhangsan", 22, "male"));
persons.add(new Person("lisi", 25, "male"));
persons.add(new Person("wangwu", 23, "female")); spark.createDataFrame(persons, Person.class).show(false); spark.close(); }
}
然后创建SparkLauncher类:
import org.apache.spark.launcher.SparkAppHandle;
import org.apache.spark.launcher.SparkLauncher; import java.io.IOException; public class Launcher {
public static void main(String[] args) throws IOException {
SparkAppHandle handler = new SparkLauncher()
.setAppName("hello-world")
.setSparkHome(args[0])
.setMaster(args[1])
.setConf("spark.driver.memory", "2g")
.setConf("spark.executor.memory", "1g")
.setConf("spark.executor.cores", "3")
.setAppResource("/home/xinghailong/launcher/launcher_test.jar")
//此处应写类的全限定名
.setMainClass("HelloWorld")
.addAppArgs("I come from Launcher")
.setDeployMode("cluster")
.startApplication(new SparkAppHandle.Listener(){
@Override
public void stateChanged(SparkAppHandle handle) {
System.out.println("********** state changed **********");
} @Override
public void infoChanged(SparkAppHandle handle) {
System.out.println("********** info changed **********");
}
}); while(!"FINISHED".equalsIgnoreCase(handler.getState().toString()) && !"FAILED".equalsIgnoreCase(handler.getState().toString())){
System.out.println("id "+handler.getAppId());
System.out.println("state "+handler.getState()); try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
打包完成后上传到部署Spark的服务器上。由于SparkLauncher所在的类引用了SparkLauncher,所以还需要把这个jar也上传到服务器上。
[xiangcong@hnode10 launcher]$ ls
launcher_test.jar spark-launcher_2.11-2.2.0.jar
[xiangcong@hnode10 launcher]$ pwd
/home/xiangcong/launcher
由于SparkLauncher需要指定SPARK_HOME,因此如果你的机器可以执行spark-submit,那么就看一下spark-submit里面,SPARK_HOME是在哪
[xiangcong@hnode10 launcher]$ which spark2-submit
/var/lib/hadoop-hdfs/bin/spark2-submit
最后几行就能看到:
export SPARK2_HOME=/var/lib/hadoop-hdfs/app/spark # disable randomized hash for string in Python 3.3+
export PYTHONHASHSEED=0 exec "${SPARK2_HOME}"/bin/spark-class org.apache.spark.deploy.SparkSubmit "$@"
综上,我们需要的是:
- 一个自定义的Jar,里面包含Spark应用和SparkLauncher类
- 一个SparkLauncher的jar,spark-launcher_2.11-2.2.0.jar 版本根据你自己的来就行
- 一个当前目录的路径
- 一个SARK_HOME环境变量指定的目录
然后执行命令启动测试:
java -Djava.ext.dirs=/home/xinghailong/launcher -cp launcher_test.jar Launcher /var/lib/hadoop-hdfs/app/spark yarn
说明:
-Djava.ext.dirs
设置当前目录为java类加载的目录- 传入两个参数,一个是SPARK_HOME;一个是启动模式
观察发现成功启动运行了:
id null
state UNKNOWN
Mar 10, 2018 12:00:52 PM org.apache.spark.launcher.OutputRedirector redirect
INFO: 18/03/10 12:00:52 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
********** state changed **********
...省略一大堆拷贝jar的日志
********** info changed **********
********** state changed **********
Mar 10, 2018 12:00:55 PM org.apache.spark.launcher.OutputRedirector redirect
INFO: 18/03/10 12:00:55 INFO yarn.Client: Application report for application_1518263195995_37615 (state: ACCEPTED)
... 省略一堆重定向的日志
application_1518263195995_37615 (state: ACCEPTED)
id application_1518263195995_37615
state SUBMITTED
Mar 10, 2018 12:01:00 PM org.apache.spark.launcher.OutputRedirector redirect
INFO: 18/03/10 12:01:00 INFO yarn.Client: Application report for application_1518263195995_37615 (state: RUNNING)
********** state changed **********
... 省略一堆重定向的日志
INFO: user: hdfs
********** state changed **********
Mar 10, 2018 12:01:08 PM org.apache.spark.launcher.OutputRedirector redirect
INFO: 18/03/10 12:01:08 INFO util.ShutdownHookManager: Shutdown hook called
Mar 10, 2018 12:01:08 PM org.apache.spark.launcher.OutputRedirector redirect
INFO: 18/03/10 12:01:08 INFO util.ShutdownHookManager: Deleting directory /tmp/spark-f07e0213-61fa-4710-90f5-2fd2030e0701
总结
这样就实现了基于Java应用提交Spark任务,并获得其Appliation_id和状态进行定位跟踪的需求了。
在Java应用中通过SparkLauncher启动Spark任务的更多相关文章
- java 定时器中任务的启动、停止、再启动
package com.cvicse.ump.timer.service; import java.util.Date; import java.util.Timer; import com.cvic ...
- 利用SparkLauncher 类以JAVA API 编程的方式提交Spark job
一.环境说明和使用软件的版本说明: hadoop-version:hadoop-2.9.0.tar.gz spark-version:spark-2.2.0-bin-hadoop2.7.tgz jav ...
- eclipse java项目中明明引入了jar包 为什么项目启动的时候不能找到jar包 项目中已经 引入了 com.branchitech.app 包 ,但时tomcat启动的时候还是报错? java.lang.ClassNotFoundException: com.branchitech.app.startup.AppStartupContextListener java.lang.ClassN
eclipse java项目中明明引入了jar包 为什么项目启动的时候不能找到jar包 项目中已经 引入了 com.branchitech.app 包 ,但时tomcat启动的时候还是报错?java. ...
- idea中使用scala运行spark出现Exception in thread "main" java.lang.NoClassDefFoundError: scala/collection/GenTraversableOnce$class
idea中使用scala运行spark出现: Exception in thread "main" java.lang.NoClassDefFoundError: scala/co ...
- 在 Azure HDInsight 中安装和使用 Spark
Spark本身用Scala语言编写,运行于Java虚拟机(JVM).只要在安装了Java 6以上版本的便携式计算机或者集群上都可以运行spark.如果您想使用Python API需要安装Python解 ...
- spark-shell启动spark报错
前言 离线安装好CDH.Coudera Manager之后,通过Coudera Manager安装所有自带的应用,包括hdfs.hive.yarn.spark.hbase等应用,过程很是波折,此处就不 ...
- H01-Linux系统中搭建Hadoop和Spark集群
前言 1.操作系统:Centos7 2.安装时使用的是root用户.也可以用其他非root用户,非root的话要注意操作时的权限问题. 3.安装的Hadoop版本是2.6.5,Spark版本是2.2. ...
- Spark Standalone Mode 单机启动Spark -- 分布式计算系统spark学习(一)
spark是个啥? Spark是一个通用的并行计算框架,由UCBerkeley的AMP实验室开发. Spark和Hadoop有什么不同呢? Spark是基于map reduce算法实现的分布式计算,拥 ...
- Mac OSX系统中Hadoop / Hive 与 spark 的安装与配置 环境搭建 记录
Mac OSX系统中Hadoop / Hive 与 spark 的安装与配置 环境搭建 记录 Hadoop 2.6 的安装与配置(伪分布式) 下载并解压缩 配置 .bash_profile : ...
随机推荐
- G - SDOI
The Annual National Olympic of Information(NOI) will be held.The province of Shandong hold a Select( ...
- VBS数组导出到Excel
<script language="vbscript"> dim arr(9999,4) for i=0 to 9999 for j = 0 to 4 arr(i,j) ...
- 如何将MP3录音转文字
相信很多人都有电话录音的习惯,因为这样可以记录下很多重要的信息.那么当我们通过录音将一些重要的信息记录下来后,我们应该怎样将这些录音文件转换成文字进行记录呢?下面我们就一起来看一下吧. 操作步骤: 步 ...
- db2pd工具
内容 概览 简介 使用 db2pd 工具 监控的例子 db2pd 工具 用于监控 DB2 实例和数据库的新的 DB2 UDB 工具 简介 DB2 UDB V8.2 带来了一种新工具称为 db2pd,用 ...
- 无法在Web服务器上启动调试。
Ⅰ x 操作超时 有关详细信息,请单击"帮助" x IIS--应用程序池--找到用到的程序池--回收 2 报这个错误的时候,我的IIS应用程序池只有一个>>> ...
- tensorRT 构建推理引擎
- bitmq集群高可用测试
Rabbitmq集群高可用 RabbitMQ是用erlang开发的,集群非常方便,因为erlang天生就是一门分布式语言,但其本身并不支持负载均衡. Rabbit模式大概分为以下三种:单一模式.普通模 ...
- C-Free 5 安装 [Error] G__~1.EXE: (x86)\C-FREE~1\mingw\mingw32\bin\: No such file or directory
解决[Error] g++.exe: 5\mingw\include: No such file or directory - 陆总的博客 - CSDN博客 https://blog.csdn.net ...
- oracle 11g/12c 密码复杂度验证设置
############################################################################### ###### 11g ###### ## ...
- Matlab 快捷键 命令
1. 在命令窗口(Command Window)中: 1) [上.下键]――切换到之前.之后的命令,可以重复按多次来达到你想要的命令 2) clc――清除命令窗口显示的语句,此命令并不清空当前工作区的 ...