Java版本程序开发过程主要包含三个步骤,一是map、reduce程序开发;第二是将程序编译成JAR包;第三使用Hadoop jar命令进行任务提交。

下面拿一个具体的例子进行说明,一个简单的词频统计,输入数据是一个单词文本,输出每个单词的出现个数。

一、MapReduce程序

  标准的MapReduce程序包含一个Mapper函数、一个Reducer函数和一个main函数

  

1、主程序

 package hadoop;
import org.apache.hadoop.conf.Configuration;  // 读写和保存各种配置资源
import org.apache.hadoop.fs.Path;  // 保存文件或者目录的路径
import org.apache.hadoop.io.IntWritable;  // hadoop自身定义的整形类
import org.apache.hadoop.io.Text;  // hadoop自身定义的存储字符串的类
import org.apache.hadoop.mapreduce.Job;  // 每个hadoop任务是一个Job
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;  // 读取输入
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;  // 将结果存到输出文件
import org.apache.hadoop.util.GenericOptionsParser;  // 解析hadoop的命里行参数 public class WordCount {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();  // 从hadoop配置文件里读取参数
String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();  // 从hadoop命令行读取参数
if (otherArgs.length != 2) {  // 从命令行读取的参数正常是两个,分别是输入文件和输出文件的目录
System.err.println("Usage: wordcount <in> <out>");
System.exit(2);
}
Job job = new Job(conf, "wordcount");  // 定义一个新的Job,第一个参数是hadoop配置信息,第二个参数是Job的名字
job.setJarByClass(WordCount.class);  // 根据WordCount类的位置设置Jar文件
job.setMapperClass(WordCountMapper.class);  // 设置mapper文件  
job.setReducerClass(WordCountReducer.class);  // 设置reducer文件
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); // 开始执行Job
}
}

2、mapper程序

 package hadoop;

 import java.io.IOException;
import java.util.StringTokenizer;  // java提供的字符串分隔函数 import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;  // hadoop提供的mapper基类,用户在此基础上进行自己的mapper程序开发 public class WordCountMapper extends Mapper<Object,Text,Text,IntWritable>{  // ①
IntWritable one = new IntWritable(1);
Text word = new Text(); public void map(Object key,Text value,Context context) throws IOException,InterruptedException{  // ②
StringTokenizer itr = new StringTokenizer(value.toString());  // 将字符串根据空格进行分割(value是Text类型的,所以需要将其转化成String类型进行处理)
while(itr.hasMoreTokens()){
word.set(itr.nextToken());
context.write(word,one);
}
}
}

  ① Mapper类包含四个参数,分别用来表示输入数据的key类型、value类型、输出数据的key类型和value类型。在本案例中,输入数据只有一个value没有key,所以将key类型设置为了object,值的类型是Text;对于输出数据,key类型是Text,value的类型是IntWritable。

  ② map方法包含三个参数,分别是输入数据的key类型、value类型和输出数据类型(包含了key和value)

 package hadoop;

 import java.io.IOException;

 import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer; // Reducer基类   public class WordCountReducer extends Reducer<Text,IntWritable,Text,IntWritable> {  // ①
IntWritable result = new IntWritable();
public void reduce(Text key,Iterable<IntWritable>values,Context context) throws IOException,InterruptedException{   // ②
int sum = 0;
for(IntWritable val:values){
sum += val.get();
}
result.set(sum);
context.write(key,result);
} }

  ① 和Mapper类一致,Reducer类同样包含四个参数,分别用来表示输入数据的key类型、value类型、输出数据的key类型和value类型。在本案例中,reducer的输入数据key类型为Text,值的类型是一个IntWritable的list;对于输出数据,key类型是Text,value的类型是IntWritable。

  ② reduce方法包含三个参数,分别是输入数据的key类型、value类型和输出数据类型(包含了key和value)

mapper阶段的输入 hello world hello hadoop

mapper阶段的输出 <hello 1> <world 1><hello 1> <hadoop 1>

reducer阶段的输入 <hello <1,1>> <world 1><hadoop 1>

reducer阶段的输出 <hello 2> <world 1><hadoop 1>

二、编译打包

1、编译(*.java —>*.class)

  首先进入代码目录,运行以下命令:

  javac -classpath /home/work/usr/hadoop/hadoop-1.2.1/hadoop-core-1.2.1.jar:/home/.../hadoop-1.2.1/lib/commons-cli-1.2.jar

      -d ./classes/ ./src/*.java

  (1)javac:JDK的命令行编译器

  (2)-classpath:设置需要用到的jar包路径,各个jar包之间用":"分隔

  (3)-d:设置编译后的文件存储路径,本案例中存储在./classes/下,即当前目录的classes子目录

  (4)最后一个参数是要被编译的java文件,本案例中是存储在./src/目录下的所有java文件,包含上面所讲的三个类

  注意:hadoop-2.*版本所需要用到的jar包和hadoop-1.*版本有所不同

2、打包

  jar -cvf wordcount.jar -C ./classes/ .

  (1)jar:JDK的打包命令行工具

  (2)-cvf:jar命令的参数

  

  (3)注意最后有一个.代表当前目录,把打包结果放在当前目录下

三、任务提交

1、将处理数据提交到HDFS上

  进入hadoop的安装目录,如上文 cd /home/work/usr/hadoop/hadoop-1.2.1

  (1)在集群上创建输入文件夹:./bin/hadoop fs -mkdir input

  (2)上传本地的数据文件到集群input目录:./bin/hadoop fs -put input/* input

  (3)删除集群上的输出目录(如果目录已经存在会报错):./bin/hadoop fs -rmr output(删除的时候小心点...)

2、运行程序

  ./bin/hadoop jar /../wordcount.jar hadoop.WordCount input output

  (1)jar:指定jar包的位置

  (2)hadoop.WordCount:用户自己定义的包名+主类

  (3)指定输入和输出路径

3、查看输出结果

  ./bin/hadoop fs -cat output/part-00000

注意:

(1)mapreduce程序最后的输出文件通常都是以part-00*这种方式命名的

(2)上述用到了很多hdfs的相关命令,对于hdfs上数据的访问,如果知道它的存储位置,也可以直接进入其目录进行一些查看、删除操作

(3)启动任务之后,命令行会返回当前任务的运行进度

Hadoop(二):MapReduce程序(Java)的更多相关文章

  1. Hadoop之MapReduce程序应用三

    摘要:MapReduce程序进行数据去重. 关键词:MapReduce   数据去重 数据源:人工构造日志数据集log-file1.txt和log-file2.txt. log-file1.txt内容 ...

  2. 如何在Windows下面运行hadoop的MapReduce程序

    在Windows下面运行hadoop的MapReduce程序的方法: 1.下载hadoop的安装包,这里使用的是"hadoop-2.6.4.tar.gz": 2.将安装包直接解压到 ...

  3. 用PHP编写Hadoop的MapReduce程序

    用PHP编写Hadoop的MapReduce程序     Hadoop流 虽然Hadoop是用Java写的,但是Hadoop提供了Hadoop流,Hadoop流提供一个API, 允许用户使用任何语言编 ...

  4. hadoop(二MapReduce)

    hadoop(二MapReduce) 介绍 MapReduce:其实就是把数据分开处理后再将数据合在一起. Map负责“分”,即把复杂的任务分解为若干个“简单的任务”来并行处理.可以进行拆分的前提是这 ...

  5. Hadoop之Mapreduce 程序

    package com.gylhaut.hadoop.senior.mapreduce; import java.io.IOException; import java.util.StringToke ...

  6. HADOOP之MAPREDUCE程序应用二

    摘要:MapReduce程序进行单词计数. 关键词:MapReduce程序  单词计数 数据源:人工构造英文文档file1.txt,file2.txt. file1.txt 内容 Hello   Ha ...

  7. 一起学Hadoop——使用IDEA编写第一个MapReduce程序(Java和Python)

    上一篇我们学习了MapReduce的原理,今天我们使用代码来加深对MapReduce原理的理解. wordcount是Hadoop入门的经典例子,我们也不能免俗,也使用这个例子作为学习Hadoop的第 ...

  8. 如何在Hadoop的MapReduce程序中处理JSON文件

    简介: 最近在写MapReduce程序处理日志时,需要解析JSON配置文件,简化Java程序和处理逻辑.但是Hadoop本身似乎没有内置对JSON文件的解析功能,我们不得不求助于第三方JSON工具包. ...

  9. hadoop开发MapReduce程序

    准备工作: 1.设置HADOOP_HOME,指向hadoop安装目录 2.在window下,需要把hadoop/bin那个目录替换下,在网上搜一个对应版本的 3.如果还报org.apache.hado ...

  10. 在window下远程虚拟机(centos)hadoop运行mapreduce程序

    (注:虽然连接成功但是还是执行不了.以后有时间再解决吧 看到的人别参考仅作个人笔记)先mark下 1.首先在window下载好一个eclipse.和拷贝好linux里面hadoop版本对应的插件(我是 ...

随机推荐

  1. 基本数据结构 —— 堆以及堆排序(C++实现)

    目录 什么是堆 堆的存储 堆的操作 结构体定义 判断是否为空 往堆中插入元素 从堆中删除元素 取出堆中最大的元素 堆排序 测试代码 例题 参考资料 什么是堆 堆(英语:heap)是计算机科学中一类特殊 ...

  2. BZOJ2436 [Noi2011]Noi嘉年华 【dp】

    题目链接 BZOJ2436 题解 看这\(O(n^3)\)的数据范围,可以想到区间\(dp\) 发现同一个会场的活动可以重叠,所以暴力求出\(num[l][r]\)表示离散化后\([l,r]\)的完整 ...

  3. 【bzoj1833】 ZJOI2010—count 数字计数

    http://www.lydsy.com/JudgeOnline/problem.php?id=1833 (题目链接) 题意 求在${[a,b]}$范围内整数中,每个数码出现的次数. Solution ...

  4. Qt Creater之hello world

    下载Qt Creater,博主是Qt5.2.0版本: 15:17:16 打开界面,选择文件新项目, 文件名:hellodemo: 生成的文件有.pro时项目文件,包含项目的信息,mainwindow. ...

  5. Gogs安装配置(快速搭建版)转载

    gogs官网 oschina gogs介绍 一句话描述: 一款极易搭建的自助 Git 服务. 环境 centos7:golang+mysqldb+git 安装配置环境 yum install mysq ...

  6. 微信授权,openid 分享

    https://packagist.org/packages/fcode/wxshare

  7. python基础之函数进阶之函数作为返回值/装饰器

    因为装饰器需要用到返回函数的知识,所以在这里将返回函数和装饰器合并讲解. 什么是返回函数? 我们知道,一个函数中return可以返回一个或者多个值,但其实,return不仅可以返回值,还可以返回函数. ...

  8. Nginx基础配置指令

    nginx.conf文件的结构 ... #全局块 events{ #events块 ... } http{ #http块 ... #http全局块 server{ #server块 ... #serv ...

  9. PHP7 学习笔记(二)PHP5.9 升级到PHP7 遇到的一些坑的记录(php-fpm 图解)

    apache_event_php-fpm 示意图: nginx-php-fpm示意图: Worker-Master-Server TCP-Nginx_PHP Nginx-FastCGI 1.使用$_G ...

  10. java抽象类和普通类的区别

    1.抽象类不能被实例化. 2.抽象类可以有构造函数,被继承时子类必须继承父类一个构造方法,抽象方法不能被声明为静态. 3.抽象方法只需申明,而无需实现,抽象类中可以允许普通方法有主体 4.含有抽象方法 ...