您的位置:首页 > 运维架构

开始玩hadoop8--hadoop 2.6.0实战(第一个reduce程序,ubuntu 14.04)倒排索引

2015-07-05 08:39 645 查看
前面的几次我已经把hadoop所有的过程都说了,现在正式进入学习章节

现在试着写一个reduce 程序

测试数据在:

13599999999 10086

13899999999 120

13944444444 13800138000

13722222222 13800138000

18800000000 120

13722222222 10086

18944444444 10086

第二行数据我故意写了个错误的,那个中间的空白不是“空格”而是 “制表符(Tab)”,

分割的时候故意引发数组越界异常,异常计数器加一

具体程序如下:

public class Test_2 extends Configured implements Tool {

enum Counter

{

LINESKIP,//出错的行

}

public static class Map extends Mapper<LongWritable,Text,Text,Text>

{

@Override

public void map(LongWritable key, Text value ,Context context)throws IOException, InterruptedException

{

String line=value.toString();//读取数源源

try

{

//数据处理

String[] lineSplit=line.split(" ");

String anum =lineSplit[0];

String bnum= lineSplit[1];

context.write(new Text(bnum), new Text(anum));

}

catch(java.lang.ArrayIndexOutOfBoundsException e)

{

context.getCounter(Counter.LINESKIP).increment(1);//出错 数器器加一

return;

}

}

}

public static class Reduce extends Reducer<Text,Text,Text,Text>

{

@Override

public void reduce (Text key,Iterable<Text> values, Context context) throws IOException,InterruptedException

// Iterable<Text> values 迭器器

{

String valueString;

String out="";

for(Text value:values)

{

valueString=value.toString();

out+=valueString+"|";

}

context.write(key, new Text(out));

}

}

@Override

public int run(String[] args) throws Exception {

Configuration conf =getConf();

Job job=Job.getInstance(conf,"Test_2");//任务名 旧的写法new Job(conf,"Test_2");或者加上@SuppressWarnings("deprecation")注解

job.setJarByClass(Test_2.class);//指定的class

FileInputFormat.addInputPath(job,new Path(args[0]));//输入路径

FileOutputFormat.setOutputPath(job, new Path(args[1]));//输出路径

job.setMapperClass(Map.class);//调用上面Map类作为Map任务代码

job.setReducerClass(Reduce.class);//调用上面Reduce类作为Reduce任务代码

job.setOutputFormatClass(TextOutputFormat.class);

job.setOutputKeyClass(Text.class);//指定输出的key的格式 //第个个实验和第一个实验的key类型不一样

job.setOutputValueClass(Text.class);//指定的输出的value的格式

job.waitForCompletion(true);

return job.isSuccessful()?0:1;

}

public static void main(String[] args) throws Exception

{

BasicConfigurator.configure();

//运行任务

int res =ToolRunner.run(new Configuration(), new Test_2(),args);

System.exit(res);

}

}

log4j.properties 的文件,从上一个项目的src目录拷贝过来就好了

就全部完成了

程序的结果里应该会有一个

Test_2$Counter

LINESKIP=1

这个表示程序跑成功了而且还成功记录了lineskip

这里要注意三个地方:

第一,其实以前的程序跑的太快,根本还没来得及看控制台内容,然后就翻篇了。。。

昨天我就试着像java程序那样调试一下,还真有用,结果在程序开头看到这样的:

DEBUG org.apache.hadoop.util.Shell - Failed to detect a valid hadoop home directory

java.io.IOException: HADOOP_HOME or hadoop.home.dir are not set.

这个我查了好久,没有一个靠谱的解决方法,后来在私人博客里看到:

在main方法里添加这个

System.setProperty("hadoop.home.dir", "/home/luis/hadoop-2.6.0");//路径不同于windows 下的路径,windows下是// 这儿是\

就好了。确实是。后面那个是本机的环境变量路径哦。

这里还说一下,我这里还是添加了HADOOP_HOME的环境变量。开始的时候想加在/etc/profile

可是加进去了后,怎么都识别不了。bash 说找不到对应目录。

后来想通了,因为我的hadoop 是解压安装在每个私人用户的目录下/home/luis/hadoop-2.6.0

根用户虽然有访问所有文件的最高权限,但系统启动时候的环境变量不应该会去访问用户文件夹

后来,就降一个等级,给对应用户添加环境变量:修改的是/etc/bash.bash 文件

在最下面添加:

HADOOP_HOME=/home/luis/hadoop-2.6.0

PATH=$HADOOP_HOME/bin:$PATH

然后重新启动计算机,然后在控制台输入echo $HADOOP_HOME

看看有没有看到环境变量的路径结果

2、第二个问题就是input和output的 对应输入输出类型一定要对应,否则报错。。。绝大部分的错误都会是这个问题。

job.setOutputKeyClass(Text.class);//指定输出的key的格式 //第个个实验和第一个实验的key类型不一样

//job.setOutputKeyClass(NullWritable.class);//这里我偷懒拷贝了上一个程序的代码,然后发现这里类型不对应,然后改成Text 类型就好了。

3、调试的步骤和运行步骤差不多,打好断点,然后把调试的configuration配置成和运行环境一样。

前面几步虽然可以调试,但是后面的分布式mapreduce 好像不能调试?是我的什么地方搞错了么?

这个如果有超强的java 或者hadoop 专家可以帮帮忙指导一下,我觉得程序调试才能知道程序的过程,这样才会自由方便的写程序。

最后介绍一下把写好的程序打成jar包,

右键项目--export--java--jar file--输入jar file 路径 --next--next--把main class 选上 --finish

然后对应路径下就会生成jar包,下次运行就可以直接在控制台运行了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: