WordCount
实验环境
Linux Ubuntu 14.0
jdk-7u75-linux-x64
hadoop-2.6.0-cdh5.4.5
hadoop-2.6.0-eclipse-cdh5.4.5.jar
eclipse-java-juno-SR2-linux-gtk-x86_64
实验步骤
1.切换目录到/apps/hadoop/sbin下,启动hadoop。
cd /apps/hadoop/sbin
./start-all.sh
1
2
2.在linux上,创建一个目录/data/mapreduce1。
mkdir -p /data/mapreduce1
1
3.创建/data/mapreduce1/file,
内容为:
China is my motherland
I love China
I am from China
1
2
3
4.将linux本地/data/mapreduce1/wordcount,上传到HDFS上的/mymapreduce1/in目录下。若HDFS目录不存在,需提前创建。
hadoop fs -mkdir -p /mymapreduce1/in
hadoop fs -put /data/mapreduce1/file /mymapreduce1/in
1
2
5.打开Eclipse,File–>New–>Other–>Map/Reduce Project,项目名可以随便取,如WordCount。导入所需的jar包(不详述!)
6.编写代码
(1).Mapper部分代码:
期望的Map输出类型为<单词,出现次数>
Map输入类型为<key,value>
Map输入类型最终确定为<Object,Text> //vlaue为Text类型,指每次读入文件的一行
Map输出类型最终确定为<Text,IntWritable>
public static class doMapper extends Mapper<Object, Text, Text, IntWritable>{
//第一个Object表示输入key的类型;第二个Text表示输入value的类型;第三个Text表示表示输出键的类型;第四个IntWritable表示输出值的类型
public static final IntWritable one = new IntWritable(1);
public static Text word = new Text();
@Override
protected void map(Object key, Text value, Context context) throws IOException, InterruptedException //抛出异常
{
StringTokenizer tokenizer = new StringTokenizer(value.toString(),"\t");
//StringTokenizer是Java工具包中的一个类,用于将字符串进行拆分
word.set(tokenizer.nextToken());
//返回当前位置到下一个分隔符之间的字符串
context.write(word, one);
//将word存到容器中,记一个数
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
代码解释:
在map函数里有三个参数,前面两个Object key,Text value就是输入的key和value,第三个参数Context context是可以记录输入的key和value。例如context.write(word,one);此外context还会记录map运算的状 态。map阶段采用Hadoop的默认的作业输入方式,把输入的value用StringTokenizer()方法截取出的单词设置为key, 设置value为1,然后直接输出<key,value>。
1
Reducer代码:
public static class doReducer extends Reducer<Text, IntWritable, Text, IntWritable>{
//参数同Map一样,依次表示是输入键类型,输入值类型,输出键类型,输出值类型
private IntWritable result = new IntWritable();
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context)
throws IOException, InterruptedException {
int sum = 0;
for (IntWritable value : values) {
sum += value.get();
}
//for循环遍历,将得到的values值累加
result.set(sum);
context.write(key, result);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
解释:
map输出的<key,value>先要经过shuffle过程把相同key值的所有 value聚集起来形成<key,values>后交给reduce端。reduce端接收到<key,values>之后,将 输入的key直接复制给输出的key,用for循环遍历values并求和,求和结果就是key值代表的单词出现的总次,将其设置为value,直接输 出<key,value>。
1
所导入包:
mport java.io.IOException;
import java.util.StringTokenizer;
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.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
1
2
3
4
5
6
7
8
9
10
主函数:
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
Job job = Job.getInstance();
job.setJobName(“WordCount”);
job.setJarByClass(WordCount.class);
job.setMapperClass(doMapper.class);
job.setReducerClass(doReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
Path in = new Path(“hdfs://localhost:9000/mymapreduce1/in/file”);
Path out = new Path(“hdfs://localhost:9000/mymapreduce1/out”);
FileInputFormat.addInputPath(job, in);
FileOutputFormat.setOutputPath(job, out);
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
7.在WordCount类文件中,单击右键=>Run As=>Run on Hadoop选项,将MapReduce任务提交到Hadoop中。
8.待执行完毕后,打开终端或使用hadoop eclipse插件,查看hdfs上,程序输出的实验结果。
hadoop fs -ls /mymapreduce1/out
hadoop fs -cat /mymapreduce1/out/part-r-00000
1
2
9.执行结果为:
I 2
is 1
China 3
my 1
love 1
am 1
from 1
motherland 1
参照源:https://blog.csdn.net/kai29/article/details/80841582
来源:CSDN