抛开spark-submit脚本提交spark程序
2016-06-19 18:00
483 查看
在往yarn中提交spark程序的时候,需要使用到spark-submit脚本,spark-submit脚本会启动SparkSubmit类,再反射启动用户写的spark程序。如果我们能够抛开spark-submit脚本和SparkSubmit类启动spark程序,那么spark程序就能够方便的镶嵌到其他大型程序中,为其他程序提供计算引擎,例如镶嵌到tomcat中,为web程序提供守护程序。
为了解决以上问题,首先想到的是要抛弃spark-submit,保证能够用java指令提交spark程序到yarn中。具体的分析步骤如下:
先写一个简单的示例代码用来测试,并打包,这里打包完jar包地址为/root/IdeaProjects/java-scala-practice/target/java-scala-practice-1.0.jar:
package spark.freedomstart
import org.apache.spark.sql.hive.HiveContext
import org.apache.spark.{SparkConf,
SparkContext}
object StartSparkWithoutSparkSubmit {
def main(args: Array[String]) {
val sparkConf =
new SparkConf().setAppName("local-yarn-test")
val sc =
new SparkContext(sparkConf)
val hc =
new HiveContext(sc)
hc.sql("select * from pokes").show()
}
}
查看spark-submit脚本是如何提交程序的,看到spark-submit是调用spark-class提交代码的。在spark-class脚本的最后,执行了exec "${CMD[@]}",猜测应该是使用这行指令将程序提交到yarn上的。使用echo "${CMD[@]}"把这行指令打印出来,看看具体是什么指令。
使用spark-submit提交代码,查看打印信息,执行指令,$SPARK_HOME/bin/spark-submit --master yarn --verbose --class spark.freedomstart.StartSparkWithoutSparkSubmit /root/IdeaProjects/java-scala-practice/target/java-scala-practice-1.0.jar,其中 --verbose参数是用来打印debug信息的,看到控制台弹出上一步的echo的信息,可以知道spark-class其实是用java启动了SparkSubmit来提交用户写的代码:
通过查看SparkSubmit类的源码,用户写的spark程序通过SparkSubmit中的submit->runMain方法启动,runMain方法有childArgs, childClasspath, sysProps, childMainClass四个参数影响用户提交的程序,先用--verbose,将四个参数使用spark-submit提交的时候,对应的内容打印出来。再看看能不能直接将这部分内容添加到用户程序中。这就可以抛开spark-submit脚本执行了。
可以看到4个参数的内容,Main class 和 Arguments就是启动的主类和参数,没什么好说的。System properties使用System.setProperty 加入到系统变量中;Classpath elements 是程序需要使用到的额外classpath,这部分包括--jars配置的jar包路径也要加进来,在提交程序的时候 使用java -cp指定。
通过以上几步分析,现在可以尝试修改代码,增加需要的配置,使用java指令尝试提交。
修改StartSparkWithoutSparkSubmit代码,增加需要的配置。
package spark.freedomstart
import org.apache.spark.sql.hive.HiveContext
import org.apache.spark.{SparkConf,
SparkContext}
/**
* 以下程序可以直接使用java指令启动,不需要使用spark-submit启动,也能让spark程序提交到yarn中。
*
脱离spark-submit脚本和SparkSubmit类,能够令spark程序更好的镶嵌到其他大型程序中。
*/
object StartSparkWithoutSparkSubmit {
System.setProperty("SPARK_SUBMIT","true")
System.setProperty("spark.jars","file:/root/IdeaProjects/java-scala-practice/target/java-scala-practice-1.0.jar")
System.setProperty("spark.submit.deployMode","client")
System.setProperty("spark.master","yarn-client")
def main(args: Array[String]) {
val sparkConf =
new SparkConf().setAppName("local-yarn-test")
val sc =
new SparkContext(sparkConf)
val hc =
new HiveContext(sc)
hc.sql("select * from pokes").show()
}
}
使用java指令提交spark代码,java指令需要使用 -cp参数,参数中加入的路径报错,spark的lib路径,scala的lib路径,spark的配置文件路径,hadoop的配置文件路径,用户jar包的路径和spark提交的时候--jars用到的jar包的路径。在本例中,指令如下:
java -cp \
/usr/local/spark/spark-1.6.1-bin-hadoop2.6/lib/*:\
/usr/local/spark/spark-1.6.1-bin-hadoop2.6/conf/:\
/usr/local/spark/spark-1.6.1-bin-hadoop2.6/lib/spark-assembly-1.6.1-hadoop2.6.0.jar:\
/usr/local/spark/spark-1.6.1-bin-hadoop2.6/lib/datanucleus-api-jdo-3.2.6.jar:\
/usr/local/spark/spark-1.6.1-bin-hadoop2.6/lib/datanucleus-rdbms-3.2.9.jar:\
/usr/local/spark/spark-1.6.1-bin-hadoop2.6/lib/datanucleus-core-3.2.10.jar:\
/usr/local/hadoop/hadoop-2.6.4/etc/hadoop/:\
/usr/local/scala/scala-2.10.6/lib/*:\
/root/IdeaProjects/java-scala-practice/target/java-scala-practice-1.0.jar\
-Xms1g -Xmx1g spark.freedomstart.StartSparkWithoutSparkSubmit
执行的过程中可能报错java.lang.NoSuchMethodException: akka.remote.RemoteActorRefProvider.<init>,这是因为scala中带的actor版本和spark中akka的actor版本有差异导致的,解决方法也很简单,使用java -cp提交代码的时候,要将$SCALA_HOME/lib/*放在$SPARK_HOME/lib/*后面就可以了。
到此spark程序能够通过java指令提交成功~就是这样使用的时候,参数是静态设置的,不能修改,虽然比较麻烦,但是镶嵌在别的程序中,参数从执行开始就是固定的,也比较合理。
为了解决以上问题,首先想到的是要抛弃spark-submit,保证能够用java指令提交spark程序到yarn中。具体的分析步骤如下:
先写一个简单的示例代码用来测试,并打包,这里打包完jar包地址为/root/IdeaProjects/java-scala-practice/target/java-scala-practice-1.0.jar:
package spark.freedomstart
import org.apache.spark.sql.hive.HiveContext
import org.apache.spark.{SparkConf,
SparkContext}
object StartSparkWithoutSparkSubmit {
def main(args: Array[String]) {
val sparkConf =
new SparkConf().setAppName("local-yarn-test")
val sc =
new SparkContext(sparkConf)
val hc =
new HiveContext(sc)
hc.sql("select * from pokes").show()
}
}
查看spark-submit脚本是如何提交程序的,看到spark-submit是调用spark-class提交代码的。在spark-class脚本的最后,执行了exec "${CMD[@]}",猜测应该是使用这行指令将程序提交到yarn上的。使用echo "${CMD[@]}"把这行指令打印出来,看看具体是什么指令。
使用spark-submit提交代码,查看打印信息,执行指令,$SPARK_HOME/bin/spark-submit --master yarn --verbose --class spark.freedomstart.StartSparkWithoutSparkSubmit /root/IdeaProjects/java-scala-practice/target/java-scala-practice-1.0.jar,其中 --verbose参数是用来打印debug信息的,看到控制台弹出上一步的echo的信息,可以知道spark-class其实是用java启动了SparkSubmit来提交用户写的代码:
通过查看SparkSubmit类的源码,用户写的spark程序通过SparkSubmit中的submit->runMain方法启动,runMain方法有childArgs, childClasspath, sysProps, childMainClass四个参数影响用户提交的程序,先用--verbose,将四个参数使用spark-submit提交的时候,对应的内容打印出来。再看看能不能直接将这部分内容添加到用户程序中。这就可以抛开spark-submit脚本执行了。
可以看到4个参数的内容,Main class 和 Arguments就是启动的主类和参数,没什么好说的。System properties使用System.setProperty 加入到系统变量中;Classpath elements 是程序需要使用到的额外classpath,这部分包括--jars配置的jar包路径也要加进来,在提交程序的时候 使用java -cp指定。
通过以上几步分析,现在可以尝试修改代码,增加需要的配置,使用java指令尝试提交。
修改StartSparkWithoutSparkSubmit代码,增加需要的配置。
package spark.freedomstart
import org.apache.spark.sql.hive.HiveContext
import org.apache.spark.{SparkConf,
SparkContext}
/**
* 以下程序可以直接使用java指令启动,不需要使用spark-submit启动,也能让spark程序提交到yarn中。
*
脱离spark-submit脚本和SparkSubmit类,能够令spark程序更好的镶嵌到其他大型程序中。
*/
object StartSparkWithoutSparkSubmit {
System.setProperty("SPARK_SUBMIT","true")
System.setProperty("spark.jars","file:/root/IdeaProjects/java-scala-practice/target/java-scala-practice-1.0.jar")
System.setProperty("spark.submit.deployMode","client")
System.setProperty("spark.master","yarn-client")
def main(args: Array[String]) {
val sparkConf =
new SparkConf().setAppName("local-yarn-test")
val sc =
new SparkContext(sparkConf)
val hc =
new HiveContext(sc)
hc.sql("select * from pokes").show()
}
}
使用java指令提交spark代码,java指令需要使用 -cp参数,参数中加入的路径报错,spark的lib路径,scala的lib路径,spark的配置文件路径,hadoop的配置文件路径,用户jar包的路径和spark提交的时候--jars用到的jar包的路径。在本例中,指令如下:
java -cp \
/usr/local/spark/spark-1.6.1-bin-hadoop2.6/lib/*:\
/usr/local/spark/spark-1.6.1-bin-hadoop2.6/conf/:\
/usr/local/spark/spark-1.6.1-bin-hadoop2.6/lib/spark-assembly-1.6.1-hadoop2.6.0.jar:\
/usr/local/spark/spark-1.6.1-bin-hadoop2.6/lib/datanucleus-api-jdo-3.2.6.jar:\
/usr/local/spark/spark-1.6.1-bin-hadoop2.6/lib/datanucleus-rdbms-3.2.9.jar:\
/usr/local/spark/spark-1.6.1-bin-hadoop2.6/lib/datanucleus-core-3.2.10.jar:\
/usr/local/hadoop/hadoop-2.6.4/etc/hadoop/:\
/usr/local/scala/scala-2.10.6/lib/*:\
/root/IdeaProjects/java-scala-practice/target/java-scala-practice-1.0.jar\
-Xms1g -Xmx1g spark.freedomstart.StartSparkWithoutSparkSubmit
执行的过程中可能报错java.lang.NoSuchMethodException: akka.remote.RemoteActorRefProvider.<init>,这是因为scala中带的actor版本和spark中akka的actor版本有差异导致的,解决方法也很简单,使用java -cp提交代码的时候,要将$SCALA_HOME/lib/*放在$SPARK_HOME/lib/*后面就可以了。
到此spark程序能够通过java指令提交成功~就是这样使用的时候,参数是静态设置的,不能修改,虽然比较麻烦,但是镶嵌在别的程序中,参数从执行开始就是固定的,也比较合理。
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- Spark RDD API详解(一) Map和Reduce
- 使用spark和spark mllib进行股票预测
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序