hadoop编程入门学习笔记-2 通过示例程序理解hadoop

时间:2022-09-24 22:50:57

一、运行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方法就是这样一个驱动。