开始玩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包,下次运行就可以直接在控制台运行了。
现在试着写一个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包,下次运行就可以直接在控制台运行了。
相关文章推荐
- [Linux同步]读写信号量
- Linux makefile 教程 非常详细,且易懂
- boost.asio学习笔记一、linux下boost库的安装
- 鸟哥的Linux私房菜-----13、账号管理
- 鸟哥的Linux私房菜-----12、学习使用Shell scripts
- MapReduce架构
- HDFS架构
- Linux中用stat命令查看文件时3个时间点解析
- Hadoop Spark 集群简便安装总结
- 理解Linux系统中的load average
- linux命令简单编译C代码
- 电子商务网站,前后台是否该分离?
- 转载hadoop实践路上异常问题以及相关解决方法记录
- 20条Linux命令面试问答
- ECSHOP订单自动确认
- linux中简单编译C语言
- JSP 移动端服务器tomcat中国文编码支持
- (2)Zabbix对客户端监控+报警
- PHP网站常见安全漏洞,及相应防范措施总结
- Vmware平台,Windows实机和Centos虚机共享目录hgfs问题的方法,不同于Ubuntu