注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

技术行者

时代的车轮在按照摩尔定律滚动。

 
 
 

日志

 
 

Hadoop编程入门,统计单词出现数目wordcount  

2011-09-19 15:45:00|  分类: Linux |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

编程环境:

Windows + Netbeans(在windows下编写mapReduce,然后在Linux下执行)

一、准备阶段

首先,我的java库里是很多类都没有的,因为,我到Linux系统中copy了hadoop/lib库里的必要jar,加载到了我的Netbeans里,使用eclipse的同学也需要加载到自己那边去。

这个程序使用到的包括:hadoop/hadoop-core-0.20.2-CDH3B4.jar和hadoop/lib/commons-cli-1.2.jar,建议最好将全部lib下的jar包都准备好。

 

二、编写程序(下面的是直接以hadoop官方提供的example为例子)

这个程序用于统计一批文本文件中单词出现的频率,完整的代码可在下载的 Hadoop 安装包中得到(在 src/examples/目录中)。里面有org、python等,对应的是不同版本,自行选择。我这里选择的是org的,也就是java版本。


头部信息

package org.myorg;

 

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;

下面的三个类是写在了同一个文件里的

 

1.实现Map类

这个类实现 Mapper 接口中的 map 方法,输入参数中的 value 是文本文件中的一行,利用 StringTokenizer 将这个字符串拆成单词,然后将输出结果 <单词,1> 写入到 org.apache.hadoop.mapred.OutputCollector 中。OutputCollector 由 Hadoop 框架提供, 负责收集 Mapper 和 Reducer 的输出数据,实现 map 函数和reduce 函数时,只需要简单地将其输出的 <key,value> 对往 OutputCollector 中一丢即可,剩余的事框架自会帮你处理好。

代码中 LongWritable, IntWritable, Text 均是 Hadoop 中实现的用于封装 Java 数据类型的类,这些类都能够被串行化从而便于在分布式环境中进行数据交换,你可以将它们分别视为 long, int, String 的替代品。Reporter 则可用于报告整个应用的运行进度,本例中未使用。

代码清单1                

public static class MapClass extends MapReduceBase

    implements Mapper<LongWritable, Text, Text, IntWritable>{    

    private final static IntWritable one = new IntWritable(1);

    private Text word = new Text();

    

    public void map(LongWritable key, Text value, 

                    OutputCollector<Text, IntWritable> output, 

                    Reporter reporter) throws IOException {

      String line = value.toString();

      StringTokenizer itr = new StringTokenizer(line);

      while (itr.hasMoreTokens()) {

        word.set(itr.nextToken());

        output.collect(word, one);

      }

    }

  }

 

2.实现 Reduce 类

这个类实现 Reducer 接口中的 reduce 方法, 输入参数中的 key, values 是由 Map 任务输出的中间结果,values 是一个 Iterator, 遍历这个 Iterator, 就可以得到属于同一个 key 的所有 value. 此处,key 是一个单词,value 是词频。只需要将所有的 value 相加,就可以得到这个单词的总的出现次数。 

代码清单 2                

public static class Reduce extends MapReduceBase

    implements Reducer<Text, IntWritable, Text, IntWritable> {

    

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

                       OutputCollector<Text, IntWritable> output, 

                       Reporter reporter) throws IOException {

      int sum = 0;

      while (values.hasNext()) {

        sum += values.next().get();

      }

      output.collect(key, new IntWritable(sum));

    }

  }

 

3.执行任务main程序

在 Hadoop 中一次计算任务称之为一个 job, 可以通过一个 JobConf 对象设置如何运行这个 job。此处定义了输出的 key 的类型是 Text, value 的类型是 IntWritable, 指定使用代码清单1中实现的 MapClass 作为 Mapper 类, 使用代码清单2中实现的 Reduce 作为 Reducer 类和 Combiner 类, 任务的输入路径和输出路径由命令行参数指定,这样 job 运行时会处理输入路径下的所有文件,并将计算结果写到输出路径下。然后将 JobConf 对象作为参数,调用 JobClient 的 runJob, 开始执行这个计算任务。至于 main 方法中使用的 ToolRunner 是一个运行 MapReduce 任务的辅助工具类。 

代码清单 3                

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

    Configuration conf = new Configuration();

    String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();

    if (otherArgs.length != 2) {

      System.err.println("Usage: wordcount <in> <out>");

      System.exit(2);

    }

    Job job = new Job(conf, "word count");

    job.setJarByClass(WordCount.class);

    job.setMapperClass(TokenizerMapper.class);

    job.setCombinerClass(IntSumReducer.class);

    job.setReducerClass(IntSumReducer.class);

    job.setOutputKeyClass(Text.class);

    job.setOutputValueClass(IntWritable.class);

    FileInputFormat.addInputPath(job, new Path(otherArgs[0]));

    FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));

    System.exit(job.waitForCompletion(true) ? 0 : 1);

  }

 

4. 在hadoop中的执行方式

1) 生成jar文件,将jar文件放入Linux的hadoop环境中(环境的配置方法,自行搜索)

2) 准备好,需要分析的程序文件(如下所示)

cat word.txt

peter

hello

he

she

me

me

he

she

hello

peter

hadoop

hbase

hello


3) 在hadoop上设置好目录,并将上面的这个word.txt文件放入输入目录:

/xhb/compare/input/ 输入目录

/xhb/compare/output/result/  输出目录


4) 设置执行hadoop的程序

$ cat run.sh 

#!/bin/bash

# @author xhb7636553 <xhb7636553@gmail.com>

HADOOP_PATH=/home/admin/hadoop/bin

export PATH=$HADOOP_PATH:$PATH(还有一些环境变量,根据自己系统的情况自行配置)

hadoop --config $HOME/hadoop/tb-vertical-conf jar $HOME/xhb/develop_compare_xml/Compare.jar /xhb/compare/input/ /xhb/compare/output/result


5) sh run.sh,则可以看结果啦。

$ hadoop fs -cat /xhb/compare/output/result/part-r-00000

hadoop  1

hbase   1

he      2

hello   3

me      2

peter   2

she     2

  评论这张
 
阅读(35680)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017