hive/spark之调用外部程序

        在我们使用spark过程中经常会遇到需要调用Python、shell、C++、PHP等语言编写的脚本程序。这个时候比较笨重的做法就是将这些需要调用的其他语言编写的程序翻译成spark支持的形式,这样做不仅费时费力而且有极大的可能出现翻译错误的问题。那么有没有更好的方法处理这类问题呢?以java语言为例

一、Spark RDD API

1、使用Java提供的接口执行本地命令

步骤1:创建外部脚本

#print.py
import sys
print '--start---'
getui_data_path=sys.argv[1]
print getui_data_path

步骤2:spark调用

String filePath = "./print.py";
List<String> list = Arrays.asList("1","2","3","4","5","6"); 
List<String> collect = sc.parallelize(list).map(new Function<String, String>() {
  private static final long serialVersionUID = 1L;
  @Override
  public String call(String v1) throws Exception {
	String result = null;
	String[] commands = {"python",filePath,v1};
	Process process = Runtime.getRuntime().exec(commands);//调用Python脚本
	if(process.waitFor() == 0){
		System.out.println("success");
		BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
		StringBuffer strbr = new StringBuffer();
		String line;            
		while ((line = br.readLine())!= null ){
		         strbr.append(line);
		      }
		    result = strbr.toString();
		}
	    return result;
	}
}).filter(new Function<String, Boolean>() {
	private static final long serialVersionUID = 1L;
	@Override
	public Boolean call(String v1) throws Exception {
		return v1 != null;
	}
}).collect();

2、使用spark pipe算子

步骤1:创建外部脚本

想要使用pipe要求外部脚本

1、以标准输入接收参数,标准输出返回结果,且所有输出都会被收集到spark的rdd里去,所以没有的数据不要输出,否则会引入脏数据

2、排除换行符,否则其也会进入到后面的计算

3、rdd每个分区,启动一次外部程序

#print_pipe.py
import sys

#print '--start--'
for line in sys.stdin:
  print line.strip()  #strip()主要为了排除换行符

步骤2:spark调用 

List<String> list = Arrays.asList("1","2","3","4","5","6"); 
List<String> collect = sc.parallelize(list)
.pipe("python print_pipe.py")
.collect();

建议:使用spark pipe方式调用,因为使用pipe算子是每个分区启动一次外部程序,使用Java命令形式是每条数据启动一次外部程序。而每次外部程序调用都是新开一个进程,所以其启动、关闭相对来说耗时非常大的。

但是使用pipe算子注意如果每个分区数据过多会导致外部程序OOM,当一个分区数据量过多时可以考虑一下两种方案:

1、RDD重分区:增大分区数量

2、外部程序里做策略:如获取指定数据量时触发一次处理,不要等数据全过来在处理

二、hive/spark sql + transform

...

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值