当前位置: 代码迷 >> Ruby/Rails >> hadoop学习;block数据块;地图reduce实现例子;UnsupportedClassVersionError错误;关联项目源码
  详细解决方案

hadoop学习;block数据块;地图reduce实现例子;UnsupportedClassVersionError错误;关联项目源码

热度:212   发布时间:2016-04-29 02:25:09.0
hadoop学习;block数据块;mapreduce实现例子;UnsupportedClassVersionError异常;关联项目源码

对于开源的东东,尤其是刚出来不久,我觉得最好的学习方式就是可以看源码和doc,测试它的例子

为了方便查看源码,关联导入源码的项目


先前的项目导入源码是关联了源码文件


block数据块,在配置文件hdfs-default.xml中可以查看到,记住要修改不是在这里


block文件存储块是最基本的单位


查看block存放位置,配置文件中查看



如果文件大于64M会占两个块,meta文件是校验文件,第二个文件大于64M,删除文件后,则对应block不在


datanode存放文件,一个文件可以存放在不同机器上datanode



mapreduce本身有默认的类,当什么都不写的时候,原样输出

package com.kane.mr.minidefault;


import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
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 org.apache.hadoop.util.GenericOptionsParser;

public class TestDefault {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
//GenericOptionsParser辅助工具类
   //String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
   String[] otherArgs = {"hdfs://centos:9000/kane/mini.txt","hdfs://centos:9000/kane/output"};
   if (otherArgs.length != 2) {
     System.err.println("Usage: wordcount <in> <out>");
     System.exit(2);
   }
   Job job = new Job(conf, "word count");
   job.setJarByClass(TestDefault.class);
   //中间的内容省略就采用默认的类操作,应该是原样输出
  
   FileInputFormat.addInputPath(job, new Path(otherArgs[0]));//输入参数,对应hadoop jar 对应类运行时在后面加的第一个参数
   FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));//输出参数
   System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}

然后到处该类为jar包,放到hadoop文件下,运行


接下来自己创建需要mr运行的源文件,并导入hdfs中


当我们执行hadoop命令运行时 可能出异常,因为你编写代码的jdk可能和hadoop用到的JVM不匹配


解决java.lang.UnsupportedClassVersionError问题 
Jbuilder2006自带了1.5的JDK,但如果你还想继续用JDK1.42,如果只是在Jbuilder2006的tool->configure->JDKs中添加一个JDK1.42或更低版本,那么即使你只写一个最简单的HelloWorld程序,Jbuilder2006都会给你报出长长一串错误,编写的代码在Jbuilder2005中也无法运行。JBuilder2006在运行编译工程时,会针对特定版本的VM进行编译,默认的是Java 2 SDK, v 5.0 And Late,因此,如果工程用的是1.5以下的JDK,碰到都是java.lang.UnsupportedClassVersionError这个错误。

解决的办法其实很简单,只要更改这个选项就行了。具体步骤如下:
----------------------------------------------------------
1、右键点击工程文件,选择属性(properties),
2、在属性窗口中选择 Build-->Java,在右边的选项中有四个下拉框,就可以看到编译选项了,
3、其中Compiler和Debug Option可以不用管,只在Languege features和Target VM中选择相应的JDK版本就可以了,然后确定,一切OK。
附件中是配置的图片。
-----------------------------------------------------------
如果在Target VM中选择了All Java SDKs,那么你的class文件在使用JDK1.1的VM上都可以运行(Jbuilder2006帮助中是这么说的,估计没几个人的机子上还在用JDK1.1吧 :-)
2.
Eclipse3.1同样会出现相同的问题,这时候只需要把项目用的JDK与你安装的JDK搞成版本一样就解决了.
步骤:右击你的项目-->属性-->Java Compiler,设置合适的版本!!

默认的mr程序原样输出



测试wordcount

package com.kane.mr;


import java.io.IOException;
import java.util.StringTokenizer;


import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;


public class MapperClass extends Mapper<Object,Text,Text,IntWritable>{
public Text keyText=new Text("key");
public IntWritable intValue=new IntWritable(1);
@Override
protected void map(Object key, Text value,
Context context)
throws IOException, InterruptedException {
//获取输入的值
String str=value.toString();
//用什么分隔键值,默认空格或\t 或\n
StringTokenizer sTokenizer=new StringTokenizer(str);
//循环输出,假如是My name is kane 则分四次输出四个单词
while (sTokenizer.hasMoreElements()) {
Object object = (Object) sTokenizer.nextElement();
//这里每个单词可以看做一个key
keyText.set(str);
context.write(keyText, intValue);//匹配一个就加value例如(“My”,1)
}
}

}

package com.kane.mr;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
//map传来的键值就是text 和 intwritable
public class ReducerClass extends Reducer<Text,IntWritable, Text,IntWritable>{
public IntWritable intValue= new IntWritable(0);


@Override
protected void reduce(Text key, Iterable<IntWritable> values,//假如name出现两次,这里得到的values是 name [1,1]
Context context)
throws IOException, InterruptedException {
int sum=0;
while (values.iterator().hasNext()) {
sum+=values.iterator().next().get();

}
//这里值用intwritable输出是因为很多情况下一个mapreduce的输出是下一个mapreduce的输入
intValue.set(sum);
context.write(key, intValue);
}

}

package com.kane.mr;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
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 org.apache.hadoop.util.GenericOptionsParser;


public class WordCounter {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
   String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
   if (otherArgs.length != 2) {
     System.err.println("Usage: wordcount <in> <out>");
     System.exit(2);
   }
   Job job = new Job(conf, "word count");
   job.setJarByClass(WordCounter.class);
   job.setMapperClass(MapperClass.class);
   //job.setCombinerClass(IntSumReducer.class);
   job.setReducerClass(ReducerClass.class);
   job.setOutputKeyClass(Text.class);
   job.setOutputValueClass(IntWritable.class);
   FileInputFormat.addInputPath(job, new Path(otherArgs[0]));//输入参数,对应hadoop jar 对应类运行时在后面加的第一个参数
   FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));//输出参数
   System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}



  相关解决方案