Hadoop2.6.4运行Wordcount程序

Hadoop2.6.4运行MapReduce程序

环境准备

  1. 本地jdk版本与hadoop集群的版本保持一致
  2. hadoop的jar包要全部导入

MapReduce代码实现

本代码演示 wordcount程序。
MapReduce代码实现并不难,这里要编写3个类,分别是WordcountMapper类、WordcountReducer类和WordcountDriver驱动类,前面两个类分别实现相应的 Map 和 Reduce 方法,后面一个则是对任务的创建进行部署。

分别创建这3个类,并放入wordcount package下,目录结构如下:

这里写图片描述

WordcountMapper.java

package cn.bigdata.mr.wcdemo;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
/**
 * KEYIN:默认情况下,是mr框架所读到的一行文本的起始偏移量,Long,
 * 但是在hadoop中有自己的更精简的序列化接口,所以不用Long,而用LongWritable
 * VALUEIN:默认情况下,是mr框架所读到的文本的内容,String,同上,用Text
 * KEYOUT:是用户自定义逻辑处理完成之后输出数据中的key,在此处是单词String
 * VALUEOUT:是用户自定义逻辑处理完成之后输出数据中的value,在此处是单词次数,Integer
 * 
 * @author dapao
 *
 */
public class WordcountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    /*
     * map阶段的业务逻辑就卸载自定义的map()方法中
     * maptask会对每一行输入数据调用一次我们自定义的map()方法
     * (non-Javadoc)
     * @see org.apache.hadoop.mapreduce.Mapper#map(KEYIN, VALUEIN, org.apache.hadoop.mapreduce.Mapper.Context)
     */
    @Override
    protected void map(LongWritable key, Text value, Context context)
            throws IOException, InterruptedException {

        //将maptask传给我们的文本内容先转换成String
        String line = value.toString();
        //根据空格将这一行切分成单词
        String[] words = line.split(" ");
        //将单词输出为<单词,1>
        for(String word:words){
            //将单词为key,将次数1作为value,以便后续的数据分发,可以根据单词分发,以便于相同单词会到相同的reduce task
            context.write(new Text(word), new IntWritable(1));
        }
    }

}

WordcountReducer.java

package cn.bigdata.mr.wcdemo;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
/*
 * KEYIN,VALUEIN 对应 mapper输出的KEYOUT,VALUEOUT类型对应
 * 
 * KEYOUT,VALUEOUT 是自定义reduce逻辑处理结果的输出了数据类型
 * KEYOUT是单词
 * VALUEOUT是总次数
 */
public class WordcountReducer extends Reducer<Text, IntWritable, Text, IntWritable>{ 
//extends Reducer<Text, IntWritable, Text, IntWritable> {
    /**
     * 
     * @param key
     *            是一组相同单词kv对的key
     * @param values
     * @param context
     * @throws java.io.IOException
     * @throws InterruptedException
     */

    protected void reduce(Text key, Iterable<IntWritable> values, Context context)
            throws IOException, InterruptedException {
        int count=0;
        for (IntWritable value : values) {
            count += value.get();
        }

        context.write(key, new IntWritable(count));
    }

}

WordcountDriver.java

package cn.bigdata.mr.wcdemo;

import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.WordCount;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;



public class WordcountDriver {
    /**
     * 相当于一个yarn集群的客户端 需要在此封装我们的mr程序的相关运行参数,指定jar包 最后交给yarn
     * 
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {

//      if (args == null || args.length == 0) {
//
//          args = new String[2];
//          args[0] = "hdfs://master:9000/wordcount/input/NOTICE.txt";
//          args[1] = "hdfs://master:9000/wordcount/output3";
//      }

        Configuration conf = new Configuration();
        Job job = Job.getInstance();

        // 指定本程序的jar包错在的本地路径
        job.setJarByClass(WordcountDriver.class);

        // 指定本业务job要使用的mapper业务类
        job.setMapperClass(WordcountMapper.class);
        job.setReducerClass(WordcountReducer.class);

        // 指定mapper输出数据的kv类型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        // 指定最终输出的数据的kv类型
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        // 指定job的输入原始文件所在目录
        FileInputFormat.setInputPaths(job, new Path(args[0]));

        // 指定job的输入结果所在目录
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        // 将job中配置的相关参数,以及job所用的java类所在的jar包,提交给yarn去运行
        // job.submit();
        boolean res = job.waitForCompletion(true);
        System.exit(res ? 0 : 1);

    }
}

打包工程为jar包

WordCount代码完成后,并不能直接在hadoop中运行,还需要将其打包成jvm所能执行的二进制文件,即打包成.jar文件,才能被hadoop所有。

在WordCount项目上右击,选择Export(导出),在弹出的对话框中选择 JAR file,如下图所示,然后单击Next。之后会进入JAR依赖包过滤对话框,这里只选择src即可,把lib文件夹前的勾选去掉,因为lib中的依赖包本来就是复制的hadoop的源文件,在集群中已经包含了。之后选择一个保存位置,单击Finish即可。
这里写图片描述
这里写图片描述

打包成wordcount.jar

部署并运行

部署其实就把前面打包生成的wordcount.jar包放入集群中运行。hadoop一般会有多个节点,一个namenode节点和多个datanode节点,这里只需要把jar放入namenode中,并使用相应的hadoop命令即可,hadoop集群会把任务传送给需要运行任务的节点。wordcount.jar运行时需要有输入文本。

  • 上传测试文件到HDFS

hadoop fs -mkdir /wordcount/input #设置输入
hadoop fs -put a.txt b.txt c.txt /wordcount/input #上传测试文本

  • 在hadoop集群中运行WordCount

    在hadoop中运行jar任务需要使用的命令:
    这里写图片描述

    hadoop: hadoop脚本命令,如果要直接使用,必须添加相应bin路径到环境变量PATH中。
    jar: 表示要运行的是一个基于Java的任务。
    jar文件位置: 提供所要运行任务的jar文件位置,如果在当前操作目录下,可直接使用文件名。
    jar主类: 提供入口函数所在的类,格式为[包名.]类名
    HDFS输入位置: 指定输入文件在HDFS中的位置。
    HDFS输出位置: 执行输出文件在HDFS中的存储位置,该位置必须不存在,否则任务不会运行,该机制就是为了防止文件被覆盖出现意外丢失。

本例的操作命令如下:

hadoop jar wordcount.jar cn.bigdata.mr.wcdemo.WordcountDriver /wordcount/input /wordcount/output

这里写图片描述

遇到的问题

  • 问题一:
    这里写图片描述

    解决方法:
    这里写图片描述

    -问题二:
    这里写图片描述

    解决方法:

这里写图片描述

有时候一个引错包,或者配置文件写错,就会调试好长时间,对此,小伙伴们要细心细心再细心

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值