IDEA远程调试hadoop

来源:互联网 发布:手机抽签抓阄软件 编辑:程序博客网 时间:2024/04/29 10:20

以前都是在idea里面写好了hadoop程序,然后打成jar包,然后在服务器上通过jar 命令进行MR 程序的执行,这样的方式不利于调试,下面给出在idea上进行远程调试hadoop的方法。

平台

hadoop:2.6.5
OS : OSX
IDE : IDEA

注意细节

不能用maven导包,否则会报如下错误:
ERROR security.UserGroupInformation: PriviledgedActionException as:root cause:org.apache.hadoop.ipc.RemoteException:
Server IPC version 9 cannot communicate with client version 4

发现是由于hadoop-core这个包的原因导致的,但是其最高支持1.2.1 笔者没有找到解决方法。所以想在本地进行调试,只能乖乖的手动导包。

hadoop在IDEA上远程调试的步骤

1. 导如hadoop所需要的包

这一步简单的带过吧,需要导的是common, hdfs, yarn, mapreduce 四个目录下的lib下的所有包和其目录下非example的包(多导入没毛病,)额,这几个文件夹在hadoop/share/hadoop/下

2. 更改language level

更改用下图表示,,很直观
1.
这里写图片描述

2.
这里写图片描述

3.设置app 运行的参数

1. 点击Edit Configuration->传建一个application

2. 在右边的program argument 中输入服务器上HDFS的输入路径和程序的输出路径(如果程序中制定了输入输出路径,这里可以不用设置)

3. 和project directory中输入:hadoop的路径(这个hadoop可以从服务器上download一份下来,随便你放在本地什么地方)

任然上图,可以参考一下我的设置

这里写图片描述

4. 由于每一次执行后,输出路径不会自动的删除,如果我们的输出路径不修改,那么程序会报输出文件已存在的错误,如下:

Exception in thread "main" org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory hdfs://master1:9000/flow/output already exists

解决方法:
1. 去服务器上吧output paht 给手动删除了
2.写代码
个人喜欢第二种,既然用本地远程调试了,还跑去服务器上一次一次的删,太麻烦了。下面给出删除的代码,其实就是HDFS的操作:

import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.FSDataOutputStream;import org.apache.hadoop.fs.FileSystem;import org.apache.hadoop.fs.Path;import java.io.IOException;import java.net.URI;import java.net.URISyntaxException;/** * Created by macan on 2017/1/14. */public class HdfsConnection {    private FileSystem fs = null;    public HdfsConnection() throws URISyntaxException, IOException, InterruptedException {        Configuration conf = new Configuration();        conf.set("fs.defaultFS", "hdfs://master1:9000");        fs = FileSystem.get(new URI("hdfs://master1:9000"), conf, "root");    }    /**     * 删除HDFS 中指定的目录     * @param path  需要删除的目录     * @param is 是否进行递归删除文件     * @throws IOException     */    public boolean delete(String path, boolean is) throws IOException {        boolean res = true;        if (exits(path)) {            res = fs.delete(new Path(path), is);            fs.close();        }        return res;    }    /**     * 查看文件是否存在     * @param path 文件路径     * @return 如果文件存在,返回true,否则返回false     * @throws IOException     */    public boolean exits(String path) throws IOException {        boolean res = fs.exists(new Path(path));        return res;    }}

在MR的主程序中调用示例:

import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.Path;import org.apache.hadoop.io.Text;import org.apache.hadoop.mapreduce.Job;import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;import java.io.IOException;import java.net.URISyntaxException;/** * Created by macan on 2017/1/14. */public class FlowCountWithPartitioner {    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException, URISyntaxException {        if (args.length < 2){            System.out.println("please input 2 args, one is input path and second is output path");            System.exit(-1);        }        //删除hdfs上的output 路径        HdfsConnection hdfs = new HdfsConnection();        hdfs.delete(args[1], true);        Configuration conf = new Configuration();        Job job = Job.getInstance(conf);        //指定本程序jar包所在的目录        job.setJarByClass(FlowCountWithPartitioner.class);        //指定本业务的job要使用的mapper/reduce 的业务类        job.setMapperClass(FlowCountMapper.class);        job.setReducerClass(FlowCountReduce.class);        //指定自定义的Partiotioner        job.setPartitionerClass(ProvincePartitioner.class);        //指定相应数量的reducetask,num: 相应的数据分区数量        job.setNumReduceTasks(5);        //指定mapper的输出数据类型kv        job.setMapOutputKeyClass(Text.class);        job.setMapOutputValueClass(FlowBean.class);        //指定最终输出的数据类型        job.setOutputKeyClass(Text.class);        job.setOutputValueClass(FlowBean.class);        //指定job输出原始文件所在的目录        FileInputFormat.setInputPaths(job, new Path(args[0]));        FileOutputFormat.setOutputPath(job, new Path(args[1]));        //将job中设置的相关参数,以及所用的Java类所在的jar包,提交任务给yarn//        job.submit();        //true表示将集群中运行的结果打印出来        System.exit(job.waitForCompletion(true) ? 0 : 1);    }}

重点在22,23 行

总结

Windows上的没有使用过,改天试一下更新博客(可以看参考),如果有错误,请指教

参考

  1. http://www.jb51.net/article/88581.htm
0 0
原创粉丝点击