一个完整的hadoop程序开发过程

目的

说明hadoop程序开发过程html

前提条件

ubuntu或同类OSjava

java1.6.0_45node

eclipse-indigoapache

hadoop-0.20.2ubuntu

hadoop-0.20.2-eclipse-plugin.jarapp

各项版本必定要匹配,不然出了问题都不知道是什么缘由。框架

配置

配置Java

详见:Ubuntu下搭建JAVA开发环境及卸载eclipse

配置分布式Hadoop

详见:hadoop 0.20.2伪分布式安装详解分布式

伪分布式与分布式有两点主要区别:oop

  1. 在namenode节点配置完成hadoop之后,须要用scp把hadoop复制到datanode节点,为了方便,最好所有机器的路径都是同样的,好比都在/opt/hadoop-0.20.2中。
  2. conf目录下的masters文件要把默认的localhost改为namenode节点的主机名或IP地址,Slaves文件中,要把localhost改为datanode节点的主机名或IP

 

eclipse的hadoop插件配置

hadoop-0.20.2-eclipse-plugin.jar是一个 eclipse中的hadoop插件。

它的做用是实现了HDFS的可视化操做,若是没有它,就要在大量地在终端输入命令,每一个命令都是以bin/hadoop dfs开头。

若是你是新手,可能还以为很新鲜,若是很熟悉命令的话,就会以为很烦。新手总会变成老手,因此这个插件仍是有必要的。

下面简单说一下配置过程:

eclipse和hadoop-eclipse-plugin这套插件的版本要求很是高,必定要高度匹配才能用。另外一篇博文写了一部分对应关系:https://www.cnblogs.com/Sabre/p/10621064.html

1.下载hadoop-0.20.2-eclipse-plugin.jar,自行搜索。官网不太容易找旧版本。

2.把此jar放到eclipse插件目录下,通常是plugins目录

从新启动eclipse,若是版本正确,此时在eclipse中的project exporer中应该能够看到DFS Locations项。若是没有出现,极可能是版本的问题。

 

3.配置Hadoop所在目录。eclipse-->window菜单-->Preferences-->Hadoop Map/Reduce,右侧输入或选择你的Hadoop目录

4.显示Map/Reduce Locations窗口。eclipse-->window菜单-->Open Perspective-->Other,选择蓝色的小象图标Map/Reduce,会在下面出黄色的小象窗口,Map/Reduce Locations

5.配置Hadoop LocationMap/Reduce Locations中右键,New Hadoop Location,出现配置窗口,location name随便你写。下面的Map/Reduce Master框中的host,若是是分布式就用IP或主机名,不要用默认的localhost。port改为9000。DFS Master框中的Use M/R Master host默认打勾保持不变,下面的Port改为9001 。user name 通常默认中不中 ,    

 至此,eclipse的hadoop插件就配置完成了。

编写程序

如下的程序是从《hadoop实战》中脱胎出来的,之因此说脱胎,是由于原书中的代码缺乏不少条件,不加以完善是没法运行的。这本书写得很差,感受是为了评职称之类的事情,让学生给凑的,里面不少硬伤。之因此还在硬着头皮看下去,是由于多少仍是讲了一些东西,同时也挑战一下本身,面对不那么完善的环境时,可否解决问题,而不是一味地寻找更好的教材,这是在豆瓣上写的一篇书评:https://book.douban.com/review/10071283/

 1.打开eclipse,新建java项目。右键项目,properties,Java Builder Path,Libraries,Add External JARS,找到hadoop的目录,把根目录下的几个jar包都添加进来。

2.新建类,Score_process.java,复制粘贴如下代码:

package pkg1; import java.net.URI; import java.util.Iterator; import java.util.StringTokenizer; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configured; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.input.TextInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.util.Tool; import org.apache.hadoop.util.ToolRunner; public  class Score_process extends Configured implements Tool { //内部类Map
    public static class Map extends Mapper<LongWritable, Text, Text, IntWritable> { //map方法
        public void map(LongWritable key, Text value, Context context) throws java.io.IOException ,InterruptedException { System.out.println("key值:" + key); String line = value.toString();//将输入的纯文本文件的数据转化为string //将输入的数据按行分割
            StringTokenizer tokenizerArticle = new StringTokenizer(line, "\n"); //分别对每一行进行处理
            while (tokenizerArticle.hasMoreTokens()) { //每行按空格划分
                StringTokenizer tokenizerLine = new StringTokenizer(tokenizerArticle.nextToken()); String nameString = tokenizerLine.nextToken(); String scoreString = tokenizerLine.nextToken(); Text name = new Text(nameString); int scoreInt = Integer.parseInt(scoreString); context.write(name, new IntWritable(scoreInt));//输出姓名和成绩
 } }; } //内部类Reduce
    public static class Reduce extends Reducer<Text, IntWritable, Text, IntWritable> { //reduce方法
        public void reduce(Text key, java.lang.Iterable<IntWritable> values, Context context) throws java.io.IOException ,InterruptedException { int sum=0; int count=0; Iterator<IntWritable> iterator = values.iterator(); while (iterator.hasNext()) { sum += iterator.next().get(); count++; } int average = (int)sum/count; context.write(key, new IntWritable(average)); }; } public int run(String[] args) throws Exception { Configuration configuration = getConf(); //configuration.set("mapred", "Score_Process.jar"); //准备环境,删除已经存在的output2目录,保证输出目录不存在**开始************
        final String uri = "hdfs://192.168.1.8:9000/"; FileSystem fs = FileSystem.get(URI.create(uri),configuration); final String path = "/user/grid/output2"; boolean exists = fs.exists(new Path(path)); if(exists){ fs.delete(new Path(path),true); } //准备环境,删除已经存在的output2目录,保证输出目录不存在**结束************
 Job job= new Job(configuration); job.setJobName("Score_process"); job.setJarByClass(Score_process.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); job.setMapperClass(Map.class); job.setCombinerClass(Reduce.class); job.setReducerClass(Reduce.class); job.setInputFormatClass(TextInputFormat.class); job.setOutputFormatClass(TextOutputFormat.class); FileInputFormat.setInputPaths(job, new Path(args[0])); // System.out.println(new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1])); boolean success = job.waitForCompletion(true); return success ? 0:1; } public static void main(String[] args) throws Exception { int ret = ToolRunner.run(new Score_process1(), args); System.exit(ret); } }

 

以上的代码中,有很多是套路,固定的模板。

Map是处理输入参数中给定的文本文件,处理完毕后,输出到HDFS,供reduce调用。 context.write(name, new IntWritable(scoreInt));这一句是关键。

Reduce调用map方法的结果,reduce后,写到OS文件系统。context.write(key, new IntWritable(average));这一句是关键。

整个run方法,须要改的只有setJobName和setJarByClass类的名字,其余的不用动。

整个main方法,不用动。

程序部分基本上就是这样。

 编译

终端中输入

javac -classpath /opt/hadoop-0.20.2/hadoop-0.20.2-core.jar -d ~/allTest/ScoreProcessFinal/class ~/workspace-indigo/test5/src/pkg1/Score_process.java

若是没有报错,就说明编译成功。

打包

jar -cvf ~/allTest/ScoreProcessFinal/ScoreProcessFinal.jar -C ~/allTest/ScoreProcessFinal/class .

能够用如下命令查看包里的文件:
jar vtf ~/allTest/ScoreProcessFinal/ScoreProcessFinal.jar

执行

执行能够分为两种方式,一种在eclipse中,另外一种在终端。

eclipse中运行

配置运行参数。run configurations,arguments,Program arguments:

文本框中输入:hdfs://host-thinkpad:9000/user/grid/input2 hdfs://host-thinkpad:9000/user/grid/output2

就是输入目录和输出目录,注意中间有个空格。

 

终端中运行

/opt/hadoop-0.20.2/bin/hadoop jar ~/allTest/ScoreProcessFinal/ScoreProcessFinal.jar pkg1.Score_process1 input2 output2

 

这就是hadoop开发的全过程框架。

 

 

其实在此期间发生了不少各类各样的问题,分别记录在各个博文中了。

相关文章
相关标签/搜索