以pipe方式运行C++ hadoop程序时,如果想要动态设置job的参数(例如设置job name),不像用Java那么方便(可能是我没有找到对应的函数),因为在头文件 Pipes.hh 中,虽然有 JobConf 这样一个类,却没有提供相应的set方法,而只有get方法。
以设置job name为例:
在hadoop JobTracker中,当前正在运行的程序会有一个名字,即job name,如果你不在程序中指定,那么它会就使用默认名字,通常默认名字是没有太多含义的,为了便于区分,我们可以在程序中设置它。
用Java写hadoop程序时,可以用Job类的setJobName(String jobName)方法来指定,非常简单。
用C++写hadoop程序时,怎么办?如前文所述,可能是我没找到门道,在Pipes.hh中我没看到可以set属性的函数。
于是可以用另一种方法:在程序运行的时候,通过命令行传入该属性值。
先说一下,job的一些属性是在hadoop目录下的 conf/mapred-site.xml 文件中定义的,此文件中包含了很多相当于 key/value 对的东西,key就是属性名,value就是属性值,如果此文件中没有定义的属性,那么就使用其默认值。知道了这一点,我们就可以复制一份 mapred-site.xml 文件(最好不要修改原来的文件,因为我们只是临时用一用),然后向复制出来的xml文件(假设其文件名为my.xml)添加如下内容:
其中 mapred.job.name 是job name对应的属性名,MySpecialName是你要设置的job name,随你写。
有了这个文件,我们就可以这样来运行程序了:
hadoop pipes -conf my.xml -D hadoop.pipes.java.recordreader=true -D hadoop.pipes.java.recordwriter=true -input /data/ -output /my_dir/output -program /my_dir/dz_count
程序运行起来之后,你再到JobTracker中看一看,job name是不是成了“MySpecialName”?这样就解决了我们的问题。
对其他job参数,你也可以这样做。
有人说:你这哪是动态设置的,这明明是用写好的文件来传入的参数。其实不然:用C++程序动态生成一个xml文件或者修改xml文件的内容是很简单的事情,所以可以先用shell脚本调用程序,生成xml,紧接着shell脚本再带-conf参数运行C++ hadoop程序,就可以完成任务了,这也算是动态指定吧?不过整个过程是比直接使用Java写程序要麻烦。你要是知道简单的办法,请一定要留言告诉我。
注:本文基于hadoop版本0.20.2。
近期评论