一.环境说明和使用软件的版本说明:

hadoop-version:hadoop-2.9.0.tar.gz

spark-version:spark-2.2.0-bin-hadoop2.7.tgz

java-version:jdk1.8.0_151

集群环境:单机伪分布式环境。

二.适用背景

在学习Spark过程中,资料中介绍的提交Spark Job的方式主要有两种(我所知道的):第一种是通过命令行的方式提交Job,使用spark 自带的spark-submit工具提交,官网和大多数参考资料都是已这种方式提交的,提交命令示例如下:

./spark-submit --class com.learn.spark.SimpleApp --master yarn --deploy-mode client --driver-memory 2g --executor-memory 2g --executor-cores 3  ../spark-demo.jar

参数含义就不解释了,请参考官网资料。

第二种提交方式是已JAVA API编程的方式提交,这种方式不需要使用命令行,直接可以在IDEA中点击Run 运行包含Job的Main类就行,Spark 提供了以SparkLanuncher 作为唯一入口的API来实现。这种方式很方便(试想如果某个任务需要重复执行,但是又不会写linux 脚本怎么搞?我想到的是以JAV API的方式提交Job, 还可以和Spring整合,让应用在tomcat中运行),官网的示例:http://spark.apache.org/docs/latest/api/java/index.html?org/apache/spark/launcher/package-summary.html

三.文章的目地

官网已有demo和API的情况下写这篇文章的目地:官网给出的demo 放在本机跑不了。出现的现象是程序结束了,什么输出都没有或者输出JAVA_HOME is not set,虽然我调用方法设置了,然而没啥用,因此把我搜索和加上在自己思考后能够运行的demo记录下来。

四.相关demo

根据官网的示例这里有两种方式:

第一种是调用SparkLanuncher实例的startApplication方法,但是这种方式在所有配置都正确的情况下使用运行都会失败的,原因是startApplication方法会调用LauncherServer启动一个进程与集群交互,这个操作貌似是异步的,所以可能结果是main主线程结束了这个进程都没有起起来,导致运行失败。解决办法是调用new SparkLanuncher().startApplication后需要让主线程休眠一定的时间后者是使用下面的例子:

package com.learn.spark;

import org.apache.spark.launcher.SparkAppHandle;
import org.apache.spark.launcher.SparkLauncher; import java.io.IOException;
import java.util.HashMap;
import java.util.concurrent.CountDownLatch; public class LanuncherAppV {
public static void main(String[] args) throws IOException, InterruptedException { HashMap env = new HashMap();
//这两个属性必须设置
env.put("HADOOP_CONF_DIR", "/usr/local/hadoop/etc/overriterHaoopConf");
env.put("JAVA_HOME", "/usr/local/java/jdk1.8.0_151");
//可以不设置
//env.put("YARN_CONF_DIR","");
CountDownLatch countDownLatch = new CountDownLatch();
//这里调用setJavaHome()方法后,JAVA_HOME is not set 错误依然存在
SparkAppHandle handle = new SparkLauncher(env)
.setSparkHome("/usr/local/spark")
.setAppResource("/usr/local/spark/spark-demo.jar")
.setMainClass("com.learn.spark.SimpleApp")
.setMaster("yarn")
.setDeployMode("cluster")
.setConf("spark.app.id", "")
.setConf("spark.driver.memory", "2g")
.setConf("spark.executor.memory", "1g")
.setConf("spark.executor.instances", "")
.setConf("spark.executor.cores", "")
.setConf("spark.default.parallelism", "")
.setConf("spark.driver.allowMultipleContexts", "true")
.setVerbose(true).startApplication(new SparkAppHandle.Listener() {
//这里监听任务状态,当任务结束时(不管是什么原因结束),isFinal()方法会返回true,否则返回false
@Override
public void stateChanged(SparkAppHandle sparkAppHandle) {
if (sparkAppHandle.getState().isFinal()) {
countDownLatch.countDown();
}
System.out.println("state:" + sparkAppHandle.getState().toString());
} @Override
public void infoChanged(SparkAppHandle sparkAppHandle) {
System.out.println("Info:" + sparkAppHandle.getState().toString());
}
});
System.out.println("The task is executing, please wait ....");
//线程等待任务结束
countDownLatch.await();
System.out.println("The task is finished!"); }
}

注意:如果部署模式是cluster,但是代码中有标准输出的话将看不到,需要把结果写到HDFS中,如果是client模式则可以看到输出。
第二种方式是:通过SparkLanuncher.lanunch()方法获取一个进程,然后调用进程的process.waitFor()方法等待线程返回结果,但是使用这种方式需要自己管理运行过程中的输出信息,比较麻烦,好处是一切都在掌握之中,即获取的输出信息和通过命令提交的方式一样,很详细,实现如下:

package com.learn.spark;

import org.apache.spark.launcher.SparkAppHandle;
import org.apache.spark.launcher.SparkLauncher; import java.io.IOException;
import java.util.HashMap; public class LauncherApp { public static void main(String[] args) throws IOException, InterruptedException { HashMap env = new HashMap();
//这两个属性必须设置
env.put("HADOOP_CONF_DIR","/usr/local/hadoop/etc/overriterHaoopConf");
env.put("JAVA_HOME","/usr/local/java/jdk1.8.0_151");
//env.put("YARN_CONF_DIR",""); SparkLauncher handle = new SparkLauncher(env)
.setSparkHome("/usr/local/spark")
.setAppResource("/usr/local/spark/spark-demo.jar")
.setMainClass("com.learn.spark.SimpleApp")
.setMaster("yarn")
.setDeployMode("cluster")
.setConf("spark.app.id", "")
.setConf("spark.driver.memory", "2g")
.setConf("spark.akka.frameSize", "")
.setConf("spark.executor.memory", "1g")
.setConf("spark.executor.instances", "")
.setConf("spark.executor.cores", "")
.setConf("spark.default.parallelism", "")
.setConf("spark.driver.allowMultipleContexts","true")
.setVerbose(true); Process process =handle.launch();
InputStreamReaderRunnable inputStreamReaderRunnable = new InputStreamReaderRunnable(process.getInputStream(), "input");
Thread inputThread = new Thread(inputStreamReaderRunnable, "LogStreamReader input");
inputThread.start(); InputStreamReaderRunnable errorStreamReaderRunnable = new InputStreamReaderRunnable(process.getErrorStream(), "error");
Thread errorThread = new Thread(errorStreamReaderRunnable, "LogStreamReader error");
errorThread.start(); System.out.println("Waiting for finish...");
int exitCode = process.waitFor();
System.out.println("Finished! Exit code:" + exitCode); }
}

使用的自定义InputStreamReaderRunnable类实现如下:

package com.learn.spark;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; public class InputStreamReaderRunnable implements Runnable { private BufferedReader reader; private String name; public InputStreamReaderRunnable(InputStream is, String name) {
this.reader = new BufferedReader(new InputStreamReader(is));
this.name = name;
} public void run() {
System.out.println("InputStream " + name + ":");
try {
String line = reader.readLine();
while (line != null) {
System.out.println(line);
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

利用SparkLauncher 类以JAVA API 编程的方式提交Spark job的更多相关文章

  1. HDFS shell操作及HDFS Java API编程

    HDFS shell操作及HDFS Java API编程 1.熟悉Hadoop文件结构. 2.进行HDFS shell操作. 3.掌握通过Hadoop Java API对HDFS操作. 4.了解Had ...

  2. 使用JAVA API编程实现简易Habse操作

    使用JAVA API编程实现下面内容: 1.创建<王者荣耀>游戏玩家信息表gamer,包含列族personalInfo(个人信息).recordInfo(战绩信息).assetsInfo( ...

  3. java模拟表单上传文件,java通过模拟post方式提交表单实现图片上传功能实例

    java模拟表单上传文件,java通过模拟post方式提交表单实现图片上传功能实例HttpClient 测试类,提供get post方法实例 package com.zdz.httpclient; i ...

  4. 9. 使用ZooKeeper Java API编程

    ZooKeeper是用Java开发的,3.4.6版本的Java API文档可以在http://zookeeper.apache.org/doc/r3.4.6/api/index.html上找到. Ti ...

  5. RabbitMQ的Java API编程

    1.创建Maven工程,pom.xml引入依赖: <dependency> <groupId>com.rabbitmq</groupId> <artifact ...

  6. MyBatis(七):mybatis Java API编程实现增、删、改、查的用法

    最近工作中用到了mybatis的Java API方式进行开发,顺便也整理下该功能的用法,接下来会针对基本部分进行学习: 1)Java API处理一对多.多对一的用法: 2)增.删.改.查的用法: 3) ...

  7. MyBatis(六):Mybatis Java API编程实现一对多、一对一

    最近工作中用到了mybatis的Java API方式进行开发,顺便也整理下该功能的用法,接下来会针对基本部分进行学习: 1)Java API处理一对多.多对一的用法: 2)增.删.改.查的用法: 3) ...

  8. HBase环境搭建、shell操作及Java API编程

    一. 1.掌握Hbase在Hadoop集群体系结构中发挥的作用和使过程. 2.掌握安装和配置HBase基本方法. 3.掌握HBase shell的常用命令. 4.使用HBase shell命令进行表的 ...

  9. 与HDFS交互- By java API编程

    环境(ubuntu下) jdk eclipse jar(很烦,整了很久才清楚) - 导包方法 查看:https://www.cnblogs.com/floakss/p/9739030.html ()” ...

随机推荐

  1. sklearn中的回归器性能评估方法

    explained_variance_score() mean_absolute_error() mean_squared_error() r2_score() 以上四个函数的相同点: 这些函数都有一 ...

  2. rabbitmq 强制删除集群相关信息,恢复原始状态

    一.前言 同事搭的rabbitmq集群,其中一台一直报下面这种异常:  Error: {inconsistent_cluster,"Node rabbit@mq1 thinks it's c ...

  3. Python 读取目录、文件

    在读文件的时候往往需要遍历文件夹,python的os.path包含了很多文件.文件夹操作的方法.下面列出: os.path.abspath(path) #返回绝对路径 os.path.basename ...

  4. jquery <img> 图片懒加载 和 标签如果没有加载出图片或没有图片,就显示默认的图片

    参考链接:http://www.jq22.com/jquery-info390 或压缩包下载地址:链接:http://pan.baidu.com/s/1hsj8ZWw 密码:4a7s    下面是没有 ...

  5. Android开发实战(申明:来源于网络)

    Android开发实战(申明:来源于网络) 地址:http://so.csdn.net/so/search/s.do?q=Android%E5%BC%80%E5%8F%91%E5%AE%9E%E6%8 ...

  6. 2018ACM-ICPC南京区域赛M---Mediocre String Problem【exKMP】【Manacher】

    这题就单独写个题解吧.想了两天了,刚刚问了一个大佬思路基本上有了. 题意: 一个串$S$,一个串$T$,在$S$中选一段子串$S[i,j]$,在$T$中选一段前缀$T[1,k]$使得$S[i,j]T[ ...

  7. 浏览器下载Excel,直接打开显示乱码...

    情景: 浏览器中点击下载文件有两个选项:[打开][下载] [打开]之后,提示["文件.xlsx"的文件格式和扩展名不匹配.文件可能已损坏或不安全.除非您信任其来源,否则请勿打开.是 ...

  8. CCPC-Wannafly Winter Camp Day3 Div1 - 排列

    题目链接:https://zhixincode.com/contest/14/problem/A?problem_id=203 time limit per test: 1 secondmemory ...

  9. [No000013D].Net 项目代码风格参考

    1. C#代码风格要求 1.1 注释 类型.属性.事件.方法.方法参数,根据需要添加注释. 如果类型.属性.事件.方法.方法参数的名称已经是自解释了,不需要加注释:否则需要添加注释. 当添加注释时,添 ...

  10. hdu 6390 欧拉函数+容斥(莫比乌斯函数) GuGuFishtion

    http://acm.hdu.edu.cn/showproblem.php?pid=6390 题意:求一个式子 题解:看题解,写代码 第一行就看不出来,后面的sigma公式也不会化简.mobius也不 ...