Spark应用远程调试
转载来源^^ https://blog.csdn.net/u013468917/article/details/51087473
本来想用Eclipse的,然而在网上找了一圈,发现大家都在说IntelliJ如何如何好。我也受到了鼓舞,遂决定在这台破机器上鼓捣一次IntelliJ吧。
Spark程序远程调试,就是将本地IDE连接到Spark集群中,让程序一边运行,一边通过debuger实时查看运行情况,配置好以后和本地debug差不多。
之前有写过Spark集群的安装部署。http://blog.csdn.net/u013468917/article/details/50979184当时是在hadoop2.2.0平台部署的Spark1.0.2.后来对Spark熟悉了一点后,就想把集群升级以下。干脆一部到位升级到最新的1.6.1.具体的安装过程和原来的1.0.2一模一样,解压之后将原来安装文件中的conf文件夹下的配置文件直接复制过来就好了,不过用的是hadoop2.3.0的预编译包,目前还没有出现什么问题。
所以这次的演示在Spark集群1.6.1上进行。
过程大致分为以下几步:
1、打开Intellij IDEA,File->New ->Project,选择Scala。
2、取名为TopK,然后如图选择Java和Scala的SDK/
3、导入Spark依赖包,这个依赖包在压缩包的lib目录下名为 spark-assembly-XXXXXXX.jar
点击File-project structure-Libraries 点击加号选择Java
然后选择依赖包路径即可。导入依赖包后可以打开这个jar包,依次打开org-apache-spark,然后随便打开一个类,比如rdd文件夹中的RDD.class,展开这个类,点开一个属性,就会出现反编译的源码。这时源码的右上角有一个attach file,点击它,然后选择自己的spark源码的目录即可绑定源码,这时注释什么的都会显示出来。spark最新源码下载地址:https://github.com/apache/spark可以用git直接克隆到本地。git clone https://github.com/apache/spark(前提是在自己电脑中安装好git)
4、在src文件夹上右击-new-Scala Class,然后填上类名,选择object
5、在文件中填入以下内容
-
import org.apache.spark._
-
import org.apache.spark.SparkContext._
-
object TopK {
-
def main(args: Array[String]){
-
val conf = new SparkConf()
-
val sc = new SparkContext(conf)
-
val textRDD = sc.textFile(args(0),3)
-
val count = textRDD.flatMap(line => line.split("[^a-zA-Z]+").map(word=> (word,1))).reduceByKey(_+_)
-
val topk = count.mapPartitions(getTopk).collect()
-
val iter = topk.iterator
-
val outiter = getTopk(iter)
-
println("Topk的值:")
-
while(outiter.hasNext){
-
val tmp = outiter.next()
-
println("\n词: " + tmp._1 + "词频: " + tmp._2)
-
}
-
sc.stop()
-
}
-
def getTopk(iter: Iterator[(String, Int)]): Iterator[(String, Int)] = {
-
val a = new Array[(String, Int)](10)
-
while(iter.hasNext){
-
val tmp = iter.next()
-
var flag = true
-
for(i <- 0 until a.length if flag){
-
if(a(i) !=null && tmp._2 > a(i)._2){
-
for(j <- ((i+1) until a.length).reverse){a(j) = a(j-1)}
-
a(i) = tmp
-
flag = false
-
}else if(a(i) == null){
-
a(i) = tmp
-
flag = false
-
}
-
}
-
}
-
a.iterator
-
}
-
}
这是一个TopK程序,目的是找出文本中词频最高的10个词。
6、导出jar包
可能是我还不熟悉的原因,个人感觉IntelliJ导jar包比eclipse繁琐很多。
选择:File-Project Structure-Artifacts 然后点击加号,选择jar-From Modules with dependencies
然后选择Main Class为TopK,选择copy to the outputXXXXXXX点击OK。
接下来选择Build-Build Artifacts-选择build
build完成后在out文件夹下就能够看到TopK.jar了。然后将TopK.jar上传到集群主节点中。
到这里,步骤和普通应用开发一样,接下来才是重点。
7、集群配置
修改spark-class脚本 ,这个脚本在spark安装目录下的bin目录中。
修改最后两行:
done < <("$RUNNER" -cp "$LAUNCH_CLASSPATH" org.apache.spark.launcher.Main "aaa@qq.com")
修改为:
done < <("$RUNNER" -cp "$LAUNCH_CLASSPATH" org.apache.spark.launcher.Main $JAVA_OPTS "aaa@qq.com")
这就要求Spark在执行任务之前将JAVA_OPTS变量考虑进来。我们就可以为应用程序添加JVM参数啦。
修改完成后,在命令行中执行以下命令:
export JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"
这就设置好了当前的临时JVM变量。
8、远程调试开始了
首先,运行刚才上传的TopK.jar
/cloud/spark-1.6.1-bin-hadoop2.3/bin/spark-submit --class TopK --master yarn TopK.jar /Spark/Jane1.txt
这时可以看到:
说明spark正在监听5005端口,这个端口可以自己随便设,不冲突就行,但是IntelliJ默认监听这个端口。
然后回到IDEA,选择run-Edit Configuration,点击左上角的加号,选择remote,自己取个名字Test_Remote_Debug,修改一下Host,我的集群master地址是192.168.1.131
点击ok
在刚才的TopK程序中设置一个断点。
然后按F9,选择Test_Remote_Debug。
这是如果不出意外,控制台会出现
Connected to the target VM, address: '192.168.1.131:5005', transport: 'socket'
表示连接成功。接下来就可以和本地Debug一样了。
最后再啰嗦一下那个“JAVA_OPTS"字段是什么意思。
-Xdebug 启用调试特性
-Xrunjdwp 启用JDWP实现,包含若干子选项:
transport=dt_socket JPDA front-end和back-end之间的传输方法。dt_socket表示使用套接字传输。
address=5005 JVM在5005端口上监听请求,这个设定为一个不冲突的端口即可。
server=y y表示启动的JVM是被调试者。如果为n,则表示启动的JVM是调试器。
suspend=y y表示启动的JVM会暂停等待,直到调试器连接上才继续执行。suspend=n,则JVM不会暂停等待。