1.MapReduce概述
HDFS实现了分布式文件存储,存储问题解决了,我们就需要考虑如何对数据进行处理,MapReduce是一个计算框架(编程模型),基于该计算框架,可以很容易的编写数据处理程序,从而以较高的效率处理海量数据集。
MR框架对于程序员的最大意义在于,不需要掌握分布式计算编程,不需要考虑分布式编程里可能存在的种种难题,比如任务调度和分配、文件逻辑切块、位置追溯、工作。这样,程序员能够把大部分精力放在核心业务层面上,大大简化了分布式程序的开发和调试周期。
2.MapReduce的设计思想
MapReduce的设计思想简单概括而言,就是“分而治之”。整个MapReduce阶
段分为两大部分,分别是Map、Reduce。
(1)map负责“分”,即把复杂的任务分解为若干个“简单的任务”来处理。“简单的任务”包含三层含义:一是数据或计算的规模相对原任务要大大缩小;二是就近计算原则,即任务会分配到存放着所需数据的节点上进行计算;三是这些小任务可以并行计算,彼此间几乎没有依赖关系。
(2)reducer负责”合”,即对map阶段输出的处理结果进行汇总。
3.MapReduce组成架构
在MapReduce程序进行计算时,需要yarn进行资源管理,yarn主要分为ResourceManager和NodeManager两部分。
ResourceManager是一个全局的资源管理器,ResourceManager控制整个集群并管理程序向集群其他DataNode进行资源的分配。
NodeManager是每个DataNode节点上的资源和任务管理器,一方面,它会定时地向ResourceManager汇报本节点上的资源使用情况以及运行状态;另一方面,它接收并处理来自ResourceManager分配的任务。
4.WordCount第一种实现(jar)
1.启动MapReduce(先启动hadoop,命令:sh start-dfs.sh)
在启动hadoop前提下,进入hadoop中的sbin目录,执行:sh start-yarn.sh
通过jps查看是否启动:
如果有NodeManager和ResourceManager,则证明启动成功。
2.IDEA的pom.xml文件中需要的架包
<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-mapreduce-client-jobclient -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-jobclient</artifactId>
<version>2.7.1</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-mapreduce-client-core -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>2.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-common -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.1</version>
</dependency>
3.封装工具类-ClassUtil和MrUtil(自定义的封装,不是必要的,这是为了减少代码)
/**
* Title: ClassUtil
* Description: 抽象对象类
*
* @author dtt
* @data 2018-09-06 23:14
**/
public class ClassUtil {
private Class classname;
private Class okey;
private Class ovalue;
public ClassUtil(Class a,Class b,Class c){
this.classname = a;
this.okey = b;
this.ovalue = c;
}
public Class getClassname() { return classname; }
public Class getOkey() { return okey; }
public Class getOvalue() { return ovalue; }
}
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
/**
* Title: MrUtil
* Description: MapReduce工具类
*
* @author dtt
* @data 2018-09-06 22:50
**/
public class MrUtil {
private Configuration conf;
public MrUtil(){ this.conf = new Configuration(); }
public void go(String jobname, Class mapreduce, ClassUtil map, ClassUtil reduce,String iPath,String oPath) throws Exception{
// 创建job对象
Job job = Job.getInstance(conf,jobname);
// 设置运行job的类
job.setJarByClass(mapreduce);
// 设置 mapper 类
job.setMapperClass(map.getClassname());
// 设置 map 输出的key value
job.setMapOutputKeyClass(map.getOkey());
job.setOutputValueClass(map.getOvalue());
// 设置 reduce 类
job.setReducerClass(reduce.getClassname());
// 设置reduce 输出的key value
job.setOutputKeyClass(reduce.getOkey());
job.setOutputValueClass(reduce.getOvalue());
// 设置输入输出路径
FileInputFormat.setInputPaths(job,new Path(iPath));
FileOutputFormat.setOutputPath(job,new Path(oPath));
// 提交job
boolean b = job.waitForCompletion(true);
if(!b){
System.out.println(jobname + " task fail!");
} else{
System.out.println(jobname + " task success");
}
}
}
4.代码
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
/**
* Title: WordCountMapper
* Description: wordCount mapper程序
* @author dtt
* @data 2018-09-06 10:20
**/
/*
*Mapper<LongWritable, Text, Text, IntWritable>
* 其中的4个类型分别是:输入key类型、输入value类型、输出key类型、输出value类型。
* */
public class WordCountMapper extends Mapper<LongWritable, Text,Text, IntWritable> {
protected void map(LongWritable key,Text value,Context context) throws IOException,InterruptedException {
//得到输入的每一行数据
String line = value.toString();
//通过空格分割
String[] words = line.split(" ");
//循环遍历 输出
for (String word : words) {
context.write(new Text(word),new IntWritable(1));
}
}
}
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
/**
* Title: WordCountReduce
* Description: wordcount reduce程序
* @author dtt
* @data 2018-09-06 10:28
**/
/*
* Reducer<Text, IntWritable, Text, IntWritable>
* 4个类型分别指:输入key的类型、输入value的类型、输出key的类型、输出value的类型。
* */
public class WordCountReduce extends Reducer<Text, IntWritable,Text,IntWritable> {
protected void reduce(Text key,Iterable<IntWritable> values,Context context) throws IOException,InterruptedException{
Integer count = 0;
for (IntWritable value : values) {
count += value.get();
}
context.write(key, new IntWritable(count));
}
}
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.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
/**
* Title: WordCountMapReduce
* Description: wordcount 主程序
* @author dtt
* @data 2018-09-06 10:33
**/
public class WordCountMapReduce {
private static String myurl = "hdfs://自己的IP:9000";
public static void main(String[] args) throws Exception {
ClassUtil map = new ClassUtil(WordCountMapper.class,Text.class,IntWritable.class);
ClassUtil reduce = new ClassUtil(WordCountReduce.class,Text.class,IntWritable.class);
Class mr = WordCountMapReduce.class;
MrUtil job = new MrUtil();
job.go("wordcounnt",mr,map,reduce,myurl+"/wordcount/input",myurl+"/wordcount/output");
}
}
5.两种实现
1).jar包实现,点击IDEA右侧的Maven Project。点击里面的package。
在xshell中通过rz命令上传word.jar到指定目录
运行jar包:hadoop jar word.jar
2).直接运行。