最近部门在做一个查询平台,主要是为了给产品和售后自行查询日志数据,减少人为工单处理,其中涉及到一部分功能就是提交Spark任务到集群平台,上游传给我的参数主要是任务的基本信息,包括SQL和taskid,我这边将通过执行shell脚本命令的方式在脚本中以Spark-submit的方式提交任务,并且传入参数。
(1)执行shell脚本
这里关于执行脚本的方法使用以及参数传递参考:blog.csdn.net/weixin_5746…
网上的很多博客提到的都是通过exec方法建立连接建立输入流并输入命令,但是针对任务提交需要注意调用该进程的waitFor()方法等待脚本执行完毕再执行后面的语句。
(2)shell脚本提交Spark任务
脚本中最后指定执行的jar包,并将SQL以参数的形式传入jar包。
(3)Spark任务
这一步就是建立SparkSession,获取传入的SQL并执行spark.sql,最后将结果写入临时表,需要注意的是创建SparkSession的时候enableHiveSupport一定要加上,不然会报错找不到表。还有就是这样提交的任务并不会更新元数据信息,任务执行完之后我在zeeplin中查询结果的时候刚开始看不到数据以为任务执行失败了,后来refresh table xxx之后才在结果表看到结果数据,应该是hive元数据没有更新。
总结:如果是单独在机器上执行sh execute.sh命令时任务可以提交成功,在本地建一个简单脚本输出hello world并且在Java代码里面调用Runtime.getRuntime().exec(cmd)命令时也可以调用成功,但是在web程序中调用exec方法执行脚本脚本提交Spark任务则不行,关键在于waitFor方法不能少,因为exec方法会产生一个进程,Spark任务提交到集群之后脚本运行需要时间,需要等待任务执行完毕再执行后面的语句,按理来说shell只要执行了就跟主程序无关,但是经过多次测试缺少waitFor方法任务无法执行。。