目录
一、本地运行模式
1. 主要项目结构:
2. 配置pom.xml引入需要的jar包
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itcast</groupId>
<artifactId>HadoopDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>jdk.tools</groupId>
<artifactId>jdk.tools</artifactId>
<version>1.8</version>
<scope>system</scope>
<systemPath>${JAVA_HOME}/lib/tools.jar</systemPath>
</dependency>
</dependencies>
</project>
3. Map过程
package com.mr.wordcount;
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;
// k1 v1 k2 v2
public class WordCountMapper extends Mapper<LongWritable,Text,Text,IntWritable>{
private Text k=new Text();
private static final IntWritable v=new IntWritable(1);
@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, IntWritable>.Context context)
throws IOException, InterruptedException {
// TODO Auto-generated method stub
String[] str = value.toString().split(" "); //将字符串分片
for(String temp : str){
k.set(temp);
context.write(k,v);
}
}
}
4. Reduce过程
package com.mr.wordcount;
import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
// k2 v2 k3 v3
public class WordCountReduce extends Reducer<Text,IntWritable,Text,Text>{
//private IntWritable v=new IntWritable();//输出数字,,,,,,<Hello,3>
private Text v=new Text(); //输出文本,,,<Hello,<1,1,1>>
@Override
protected void reduce(Text key, Iterable<IntWritable> values,
Reducer<Text, IntWritable, Text, Text>.Context context) throws IOException, InterruptedException {
// TODO Auto-generated method stub
//输入:<Hello,1>,<world,1>,<Hello,1>,<Hello,1> map阶段的,经过shuffle(洗牌)后
//输出:<Hello,<1,1,1>>,<World,1> Reduce阶段的输入
//输出数字,,,,,,<Hello,3>
/*
int sum=0;
//1+1+1
for(IntWritable temp:value){
sum=sum+temp.get();
}
//输出k3,v3
v.set(sum);
context.write(key, v);*/
//输出<Hello,<1,1,1>>,不用求和,需要把上面的 v3 改为Text字符串类型
String str="";
for(IntWritable value:values){
str=str+value;
}
v.set(str);
context.write(key,v);
}
}
最后成功的文件输出为:
5. 核心类Driver:
package com.mr.wordcount;
import java.io.IOException;
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.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class WordCountDriver {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Configuration conf=new Configuration();
//什么也不写,,,默认本地运行
//在集群中运行,需要配置一下
conf.set("fs.defaultFS","hdfs://hadoop01:9000");
FileSystem fs=FileSystem.get(conf);//设置文件系统
Job job=Job.getInstance(conf);
//设置Mapper和Reduce
job.setJarByClass(WordCountDriver.class);
job.setMapperClass(WordCountMapper.class);
job.setReducerClass(WordCountReduce.class);
//设置输出文件个数,设置为0,没有reduce输出文件
//job.setNumReduceTasks(0);
//设置map阶段的输出类型(在这个例子中这两句可以注释掉)
job.setMapOutputKeyClass(Text.class);//k2
job.setMapOutputValueClass(IntWritable.class);//v2
//设置最终结果输出类型
job.setOutputKeyClass(Text.class);//k3
//job.setOutputValueClass(IntWritable.class);//v3
//输出文本,类型也要修改,,,,<Hello,<1,1,1>>
job.setOutputValueClass(Text.class);//v3
//==========================在windows里
/*
//设置输入输出的目录
FileInputFormat.setInputPaths(job, "E:\\applications\\eclipse\\workspace\\wordcount\\input");
//设置输出路径,如果有文件就删除
Path dst=new Path("E:\\applications\\eclipse\\workspace\\wordcount\\output");
if(fs.exists(dst)){
fs.delete(dst,true);
}
FileOutputFormat.setOutputPath(job, dst);
job.waitForCompletion(true);*/
//=========================在集群中
///*
//设置输入输出的目录
FileInputFormat.setInputPaths(job, "/mr/wordcount/input");
//设置输出路径,如果有文件就删除
Path dst=new Path("/mr/wordcount/output");
if(fs.exists(dst)){
fs.delete(dst,true);
}
FileOutputFormat.setOutputPath(job, dst);
//在集群中运行,运行路径不能用\\,必须用/
//提交job
job.waitForCompletion(true);//*/
}
}
打开集群,将input中的文件上传到搭建集群时data目录下:
上传文件到data目录下:
在jeclipse中run as --》run on hadoop后,可能会遇到权限问题,修改权限(这样修改不安全)
然后在运行的输出路径出会出现output目录:
如下表示成功
总结:
本地运行模式和集群运行模式:
- conf.set(“fs.defaultFS”,“hdfs://hadoop01:9000”); 添加这一句表示在集群中运行,默认为本地
- 在集群中添加文件路径时,不用\\,用 /
- 但是上面不是真正的集群运行,真正的集群运行模式:把MapReduce程序打成一个jar包,提交到yarn集群上去运行任务
二、集群运行模式:
1. 打包项目为jar包
一直next知道完成。
2. 上传打包的项目jar包到data目录下
3. 运行项目jar包
hadoop jar后面需要参数,如果直接运行jar包会告诉没有指定参数,后面会讲到,这里我们直接指定运行jar包中的核心类(写法为:包名+类名)
运行jar包后,就可以看到项目运行的提示,也可以看到Map过程和Reduce过程进度:
到此,这才是真正的集群运行模式。