一、运行WordCount
hdfd和yarn已运行,如果没有运行,用start-dfs.sh和start-yarn.sh运行。
1. 创建目录和准备文件
$hdfs dfs -mkdir /user $hdfs dfs -mkdir /usr/hadoop $hdfs dfs -ls / $echo "This is a test." >> test.txt $cat test.txt This is a test. $hadoop dfs -copyFromLocal test.txt $hadoop dfs -cat test.txt
2.运行WordCount
切换到示例程序hadoop-mapreduce-exapmples-2.6.0.jar所在的目录;运行命令,wordcount为所要运行的应用,test.txt为文件,out为输出的目录,part-t-00000为输出文件。
$cd /homd/hadoop//cloud/hadoop/share/hadoop/mareduce $hadoop jar hadoop-mareduce-examples-2.6.0.jar wordcount test.txt out $hadoop dfs -ls out $hadoop dfs -cat out/part-t-00000
如果out目录存在则可用hadoop dfs -rmr out 删除out目录,或重新指定一个目录。
可以用hadoop dfs -cat out/part-t-00000看输出结果,也可以用hadoop dfs -copyToLocal out/part-t-00000拷贝到本地。
二、编译自己的程序WordCount1
1.创建目录
$mkdir -p /home/hadoop/myProject/hadoop/wordcount1
2.用gedit编写WordCount1.java
保存到/home/hadoop/myProject/hadoop/wordcount1目录
import java.io.*; 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.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class WordCount1 { public static class WordCountMapper extends Mapper<Object, Text, Text, IntWritable> { private final static IntWritable one = new IntWritable(1); private Text word = new Text(); public void map(Object key, Text value, Context context) throws IOException, InterruptedException { String[] words = value.toString().split(" "); for(String str: words) { word.set(str); context.write(word, one); } } } public static class WordCountReducer extends Reducer<Text, IntWritable, Text, IntWritable> { public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { int total = 0; for(IntWritable val: values) { total++; } context.write(key, new IntWritable(total)); } } public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = new Job(conf, "word count"); job.setJarByClass(WordCount1.class); job.setMapperClass(WordCountMapper.class); job.setReducerClass(WordCountReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); System.exit(job.waitForCompletion(true)?0:1); } }
3.将WordCount1.java拷贝成test2.txt文件
$cp WrodCount1.java test2.txt
4.编写build.sh
$vi build.sh $chmod +x bhild.sh
#/bin/sh HADOOP_LIB_DIR=/home/hadoop/cloud/hadoop/share/hadoop rm -f ./*.class rm -f ./WordCount1.jar javac -classpath $HADOOP_LIB_DIR/common/hadoop-common-2.6.0.jar:$HADOOP_LIB_DIR/common/lib/commons-cli-1.2.jar:$HADOOP_LIB_DIR/common/lib/hadoop-annotations-2.6.0.jar:$HADOOP_LIB_DIR/mapreduce/hadoop-mapreduce-client-core-2.6.0.jar -d . ./WordCount1.java #package jar -cvf WordCount1.jar ./*.class
5. 编译和运行
$./build.sh $hadoop dfs -copyFromLocal test2.txt $hadoop jar WordCount1.jar WordCount1 test2.txt c1_out_001
只要classpath设置正确,就可以顺利编译,不同的版本,所引用的jar文件可能不同。
三、hadoop简介
Hadoop 是一个实现了 MapReduce 计算模型的开源分布式并行编程框架,借助于 Hadoop, 程序员可以轻松地编写分布式并行程序,将其运行于计算机集群上,完成海量数据的计算。分布式文件系统(HDFS)和资源管理器(YARN)是Hadoop提供的两个模块。HDFS提供分布式文件存储功能,YARN运行和管理同一个集群上的MapReduce批处理作业。Hadoop提供了一套MapReduce API。Hadoop做了很多事情,开发人员只要按照定义 实现map和reduce就可以了。
示例程序是统计单词出现的次数,我们可以写一个程序逐行读取,逐个计数,如果文件非常大,费时就会很长。我们来看Wordcount1示例是如何通过Hadoop是怎么来处理这个问题的。
1)首先将test2.txt文件导入HDFS(hadoop dfs -copyFromLocal test2.txt)
2)hadoop框架把文件的行当作key,每行的内容当作value给开发人员定义的map
3)执行用户定义的map,这里是用split 分离出每个单词,然后输出这个单词和次数,次数显然为1,即 (单词,1)这样的<k, v>对
4)需要执行多少个map task是有框架完成的
5)框架将map输出的相同单词(Key)的值(value)合并成<key, values<value>>的形式,传递給开发人员定义的reduce
6)reduce执行后就得到了(word, count)这样的最终结果。
简单地说,MapReduce就是实现了{ K1, v1 } -> { k2, List<v2> } -> { K3, V3 }这样的一个转换。只要能用Key/value对表达的数据,就能用hadoop来处理。在真实世界里有很多这样的例子,如地址本上的人名(key)和详细信息(value)。
为了使map和reduce能执行,需要一个驱动程序,示例里的main方法就是这样一个驱动。