一般来说,spark on yarn是将spark程序的jar包上传至服务器,然后通过spark-submit的方式。
但是,相信很多人不是一次性就能写没有bug的spark代码,都有反复调试的需求,那么,上述方式的调试效率就很低了,所以,最好的方法还是能够在本地进行yarn的提交。
实现代码
废话不多说,先献上代码
import org.apache.spark.{SparkConf, SparkContext}
class SparkYarn extends Serializable {
def yarnConnection(): Unit ={
val conf = new SparkConf().setAppName("Spark Yarn")
.set("deploy-mode", "client")
.setMaster("yarn")
.set("yarn.resourcemanager.hostname", "master")
// .set("spark.yarn.dist.files", "yarn-site.xml")
// .set("spark.executor.memory", "512M")
// .set("spark.executor.instance","1")
.set("spark.driver.host","localhost")
val sc = new SparkContext(conf)
// "/user/xxx/test/word.txt"为hdfs的路径
val lines = sc.textFile("/user/xxx/test/word.txt").flatMap(line => line.split(" ")).map(word => (word, 1))
val wordNum = lines.reduceByKey(_ + _)
wordNum.foreach(println)
}
}
object Run{
def main(args: Array[String]): Unit = {
val sy = new SparkYarn()
sy.yarnConnection()
}
}
可以发现,其实代码跟平时没什么差别,就是增加一些的配置而已。
当然,不是这么简单的事情,直接运行就可以了。
====
将集群服务器上Hadoop的配置文件core-site.xml、hdfs-site.xml、yarn-site.xml拷贝到resources目录下,其实就是加入到classpath中;不然,你也可以通过set(“spark.yarn.dist.files”, “yarn-site.xml”)来指定绝对路径。
常见问题
一、Retrying connect to server: 0.0.0.0/0.0.0.0:8032. Already tried 0 time(s)
这里其实就是无法连接上resourcemanager的问题。默认情况下,resourcemanager的ip会默认是是driver端,但如果你运行的节点不是master节点,如我们现在的本地环境,就会出问题。
<property>
<name>yarn.resourcemanager.address</name>
<value>master:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>master:8030</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>master:8031</value>
</property>
在我们项目中的yarn-site.xml文件中增加上述的配置。
master就是hadoop集群的master节点,没有进行ip映射的话,也可以用ip地址
二、ClassNotFound
出现这样的错误的话,就是spark的版本问题了。
在pom.xml或build.sbt中,将我们的spark版本改成与服务器的一致就可以了。