HDFS和MapReduce综合实训

Hadoop是一个由Apache基金会所开发的分布式系统基础架构,可以在不了解分布式底层细节的情况下,开发分布式程序,以满足在低性能的集群上实现对高容错,高并发的大数据集的高速运算和存储的需要。Hadoop支持超大文件(可达PB级),能够检测和快速应对硬件故障、支持流式数据访问、同时在简化的一致性模型的基础上保证了高容错性。因而被大规模部署在分布式系统中,应用十分广泛。

本实训的主要目标是让大家学习Hadoop的基本概念如MapReduce、HDFS等,并掌握Hadoop的基本操作,主要包括MapReduce编程(词频统计)、HDFS文件流读取操作、MapReduce迭代等。通过本次实训,建立起对Hadoop云计算的初步了解,后续大家可以通过进阶学习来深入学习Hadoop内部实现机制进行高级的应用开发。

第1关:WordCount词频统计:

词频统计是最能体现MapReduce思想的程序,结构简单,上手容易。

词频统计的大致功能是:统计单个或者多个文本文件中每个单词出现的次数,并将每个单词及其出现频率按照<k,v>键值对的形式输出,其基本执行流程如下图所示:

由图可知:

  1. 输入文本(可以不只一个),按行提取文本文档的单词,形成行<k1,v1>键值对,具体形式很多,例如<行数,字符偏移>等;
  2. 通过Spliting<k1,v1>细化为单词键值对<k2,v2>
  3. Map分发到各个节点,同时将<k2,v2>归结为list(<k2,v2>)
  4. 在进行计算统计前,先用Shuffing将相同主键k2归结在一起形成<k2,list(v2)>
  5. Reduce阶段直接对<k2, list(v2)> 进行合计得到list(<k3,v3>)并将结果返回主节点。

主节点对预设文本文档进行词频统计,并将最终结果输出。

  • 注:输入和输出事先已经预定,只要比较输出是否达到预期即可判断是否达到要求。

相关知识

MapReduce采用"分而治之"的思想,把对大规模数据集的操作,分发给一个主节点管理下的各个分节点共同完成,然后通过整合各个节点的中间结果,得到最终结果。MapReduce框架负责处理了并行编程中分布式存储、工作调度、负载均衡、容错均衡、容错处理以及网络通信等复杂问题。将处理过程高度抽象为两个函数:mapreduce

 
  1. map负责把任务分解成多个任务;
  2. reduce负责把分解后多任务处理的结果汇总起来。
  • 注:MapReduce处理的数据集必须可以分解成许多小的数据集,而且每一个小数据集都可以完全并行地进行处理。不是关系型数据库,而是结构化的。

map处理阶段

对于给定的待处理文本文档,其map阶段的处理如下:

  1. 通过Text对象,获取文本文档的内容。
  2. 逐行处理文档,将单词提取出来。
  3. 每个单词为key,对应的value设为1,将<k2,v2>对输出。

关键性说明:

  • map阶段的处理,主要是如何对文本进行逐行的单词分割,从而获取单词,以及将键值对分发到各个节点(此处由hadoop隐性提供,用户先不必关心hdfs存储过程)。
  • 可以参考的单词分割提取代码模板如下:
 
  1. public void map(Object key,Text value,Context context)throws IOException,InterruptedException
  2. {
  3. //对文本内容对象value进行分割
  4. StringTokenizer itr=new StringTokenizer(valu e.toString());
  5. while(itr.hasMoreTokens()) {
  6. String word=itr.nextToken();/*获取分割好的单词*/
  7. /*
  8. 可以在该循环体中,使用获取好的单词word变量进行key和value的设定。
  9. */
  10. }
  11. }

reduce处理阶段

Wordcountreduce阶段,主要是将每个单词的数量统计出来,包括:

  1. 在各个节点并行循环统计每个单词出现的次数。
  2. 将各个节点的结果汇总以list(<k3,v3>)的形式输出。

reduce函数参考模板:

 
  1. public void reduce(Object key,Iterable<IntWritable> values,Context context)throws IOException, InterruptedException
  2. {
  3. int count=0;
  4. for(IntWritable itr:vlaues)
  5. {
  6. count+=itr.get(); /*循环统计*/
  7. }
  8. /*统计完成后,将结果输出.....*/
  9. }

编程要求

本关的编程任务是补全右侧代码片段中mapreduce函数中的代码,具体要求及说明如下:

  • 在主函数main中已初始化hadoop的系统设置,包括hadoop运行环境的连接。
  • main函数中,已经设置好了待处理文档路径(即input),以及结果输出路径(即output)。
  • main函数中,已经声明了job对象,程序运行的工作调度已经设定好。
  • 本关只要求在mapreduce函数的指定区域进行代码编写,其他区域请勿改动。

测试说明

以下是测试样例:

测试输入样例数据集:文本文档test1.txttest2.txt

  • 文档test1.txt中的内容为:
    tale as old as time
    true as it can be
    beauty and the beast

  • 文档test2.txt中的内容为:
    ever just the same
    ever as before
    beauty and the beast

预期输出result.txt文档中的内容为:
and 2
as 4
beast 2
beauty 2
before 1
can 1
ever 2
it 1
just 1
old 1
same 1
tale 1
the 3
time 1
true 1

代码: 

import java.io.IOException;

import java.util.StringTokenizer;

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;

import org.apache.hadoop.util.GenericOptionsParser;

public class WordCount {

  public static class TokenizerMapper 

       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 {

        StringTokenizer itr = new StringTokenizer(value.toString());

        while (itr.hasMoreTokens()){

            word.set(itr.nextToken());

            context.write(word,one);

        }

    /*********begin*********

 

    /*********end**********/

    }

  }

  public static class IntSumReducer 

       extends Reducer<Text,IntWritable,Text,IntWritable> {

    private IntWritable result = new IntWritable();

    public void reduce(Text key, Iterable<IntWritable> values, 

                       Context context

                       ) throws IOException, InterruptedException {

    /*********begin*********/

    int sum = 0;

    for (IntWritable val : values){

        sum += val.get(); 

    }

    result.set(sum);

    context.write(key,result);




 

    /*********end**********/

    /*********begin*********/





 

    /*********end**********/

    }

}

  public static void main(String[] args) throws Exception {

      /**

       * JobConf£ºmap/reduceµÄjobÅäÖÃÀ࣬Ïòhadoop¿ò¼ÜÃèÊömap-reduceÖ´ÐеŤ×÷ 

       * ¹¹Ôì·½·¨£ºJobConf()¡¢JobConf(Class exampleClass)¡¢JobConf(Configuration conf)µÈ 

       */  

    Configuration conf = new Configuration();

    String[] otherArgs = new GenericOptionsPa

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cz学java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值