python调用spark服务无法执行SQL文件

问题描述

  • 问题来源
在ETL任务中,需要使用java服务调用python脚本完成mysql数据同步,然后使用spark-sql 执行SQL脚本进行数据加载;另外还有跨天同步时,需要进行数据跨天合并,因此会在python脚本中,再次调用跨天python脚本,使用Spark-SQL完成多天数据加载。
但在Spark-SQL执行SQL文件时,发现无法执行相应的SQL文件,并无报错,Spark-SQL也提交application到yarn集群

在这里插入图片描述

问题定位

1 java服务调用

  • 1.1 调用问题
java 使用Process 完成shell命令调用
String cmd = "spark-sql -f " + sql_path;
Process process = Runtime.getRuntime().exec(cmd);
但是对于复杂的shell命令,无法进行正确解析,导致执行失败,需要对cmd进行如下处理
String cmd = "spark-sql -f " + sql_path;
StringTokenizer st = new StringTokenizer(cmd);
String[] cmdarray = new String[st.countTokens()];
for (int i = 0; st.hasMoreTokens(); i++) cmdarray[i] = st.nextToken();
Process process = Runtime.getRuntime().exec(cmdarray);
  • 1.2 解决情况
发现修改后,仍然无法进行命令调用

2.python脚本调用

  • 2.1 python调用shell命令
python 有如下命令
os.system(cmd),
commands.getstatusoutput(cmd),
subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE):不会阻塞主进程执行业务


现有程序使用os.system(cmd),现在改成commands.getstatusoutput(cmd)进行spark-sql执行SQL文件
  • 2.2 解决情况
可以成功执行

问题总结

初步判断是 python执行spark-sql 命令时,
使用模块执行 spark-sql 命令失败原因,
后续进行调研发现,os.system(cmd)执行shell命令,
既阻塞主进程,也会造成某些命令无法执行

python脚本执行使用模块

  • 1.os.system(cmd)
(1).同步执行,阻塞至执行结果返回
(2).返回值依赖于系统,所以windows和Linux的返回值可能会有差异
  • 2.wx.Execute(command, syn=wx.EXEC_ASYNC, callback=None)
(1). 分同步异步,若设置为若syn=wx.EXEC_ASYNC则等待调用的程序结束后再返回,需要callback函数,callback是一个wx.Process变量,callback不为None时,则程序结束后将调研wx.Process.OnTerminate()函数;
若置syn为wx.EXEC_SYNC则wx.Excute函数立即返回
(2).os.system()和wx.Execute()都利用系统shell,执行时会出现shell窗口
(3).
(4).
(5).
  • 3.commands,推荐
(1).执行完毕会返回状态值和执行结果
(2).使用例子
 import commands
 # 返回状态值和结果,linux下0为执行成功
 命令执行成: 
 commands.getstatusoutput('pwd')
 (0, '/data/program/datax2canal')
 命令执行失败: 
 commands.getstatusoutput('ls abc')
(512, 'ls: cannot access abc: No such file or directory')
(0, '/bin/ls')
#返回执行结果
 commands.getoutput('pwd')
'/data/program/datax2canal'
#返回状态值
commands.getstatus('/bin/ls')
'-rwxr-xr-x 1 root root 117048 Mar 23  2017 /bin/ls'

  • 4.subprocess,推荐
(1).不阻塞主进程执行
(2).使用例子,返回状态值和标准输出信息,错误输出信息
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, errout = p.communicate()
    if p.returncode != 0:
        print "do cmd = %s failed, return=%d" % (cmd, p.returncode)
        print 'errout: ' + errout
        return p.returncode, stdout, errout
  • 5.os.popen(command[,mode[,bufsize]])
(1).通过p.read()获取终端输出,popen需要关闭close().
(2).当执行成功时,close()不返回任何值,失败时,close()返回系统返回值
(3).例子
import os
#正常执行
p = os.popen('pwd')
p.read()
'/data/program/datax2canal\n'
p.close()
#执行失败
p2 = os.popen('ls abc')
ls: cannot access abc: No such file or directory
#读取值为空
p2.read()
''
#返回错误状态值
p2.close()
512
  • 6.webbrowser.open(url)
(1).执行URL
(2).调用系统缺省浏览器打开URL地址
webbrowser.open('http:/localhost:8080/test'),
(3).执行程序
webbrowser.open('h:\python.zip')
(4).
(5).
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值