什么是分布式计算?
分布式计算:是一种计算方法,是将该应用分解成许多小的部分,分配给多台计算机进行处理。这样可以节约整体计算时间,大大提高计算效率。
很简单的一句话:众人拾柴火焰高
理解MapReduce思想
MapReduce的思想核心是“分而治之,先分后合”。即将一个大的、复杂的工作或任务,拆分成多个小的任务,并行处理,最终进行合并。适用于大量复杂的、时效性不高的任务处理场景(大规模离线数据处理场景)。即使是发布过论文实现分布式计算的谷歌也只是实现了这种思想,而不是自己原创。
MapReduce由两部分组成,分别是Map 和Reduce两部分。
Map负责“分”,即把复杂的任务分解为若干个“简单的任务”来并行处理。
Reduce负责“合”,即对map阶段的结果进行全局汇总。
MapReduce并行计算
HDFS存储数据时对大于128M的数据会进行数据切分,每128M一个数据块,数据块会分散、分布存储到HDFS。
MapReduce在进行计算前会复制计算程序,每个数据块会分配一个独立的计算程序副本(MapTack)。计算时多个数据块几乎同时被读取并计算,但是计算程序完全相同。最终将各个计算程序计算的结果进行汇总(Reduce来汇总)
Hadoop -MapReduce设计构思
MapReduce是一个分布式运算程序的编程框架,核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在Hadoop集群上。
既然是做计算的框架,那么表现形式就是有个输入(input),MapReduce操作这个输入(input),通过本身定义好的计算模型,得到一个输出(output)。
Hadoop MapReduce构思体现在如下的三个方面:
如何应对大数据处理:分而治之
对相互间不具有计算依赖关系的大数据,实现并行最自然的办法就是采取分而治之的策略。并行计算的第一个重要问题是如何划分计算任务或者计算数据以便对划分的子任务或数据块同时进行计算。不可分拆的计算任务或相互间有依赖关系的数据无法进行并行计算!
构建抽象模型:Map和Reduce
MapReduce借鉴了函数式语言中的思想,用Map和Reduce两个函数提供了高层的并行编程抽象模型。
Map: 对一组数据元素进行某种重复式的处理;
Reduce: 对Map的中间结果进行某种进一步的结果整理。
MapReduce中定义了如下的Map和Reduce两个抽象的编程接口,由用户去编程实现:
map: [k1,v1] → [(k2,v2)] :(key,value)的list;
reduce: [k2, {v2,…}] → [k3, v3] :key,(value的list);
编程初步体验
WordCount案例:
数据:
hello,world,hadoop
hello,hive,sqoop,flume
kitty,tom,jerry,world
hadoop
创建maven项目源码如下:
pom所需的jar包:
<dependency>
<groupId>org.apache.Hadoop</groupId>
<artifactId>Hadoop-client</artifactId>
<version>2.6.0-mr1-cdh5.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.Hadoop</groupId>
<artifactId>Hadoop-common</artifactId>
<version>2.6.0-cdh5.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.Hadoop</groupId>
<artifactId>Hadoop-hdfs</artifactId>
<version>2.6.0-cdh5.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.Hadoop</groupId>
<artifactId>Hadoop-mapreduce-client-core</artifactId>
<version>2.6.0-cdh5.14.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>RELEASE</version>
</dependency>
定义一个mapper 类:
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
public class mapSamCount extends Mapper<LongWritable,Text,Text,LongWritable> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String[] split = value.toString().split(",");
for (String s : split) {
context.write(new Text(s), new LongWritable(1));
}
}
}
定义一个reduce 类:
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
public class reduceSamCount extends Reducer<Text, LongWritable, Text, LongWritable> {
@Override
protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
int count =0;
for (LongWritable value : values) {
count+= value.get();
}
context.write(key,new LongWritable(count));
}
}
驱动类:
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
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 JobMain {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "SamCount");
//设置驱动类类
job.setJarByClass(JobMain.class);
//设置map类
job.setMapperClass(mapSamCount.class);
//设置reduce类
job.setReducerClass(reduceSamCount.class);
//map输出的格式
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);
//reduce输出的格式
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
//文件的输入路径
FileInputFormat.addInputPath(job, new Path(args[0]));
//文件输出的路径
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
到此一个简单的Wordcount案例就结束了,相信对MapReduce有一个初步的了解了吧