MapReduce(一)
一。介绍
百度百科:
MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算。概念"Map(映射)"和"Reduce(归约)",是它们的主要思想,都是从函数式编程语言里借来的,还有从矢量编程语言里借来的特性。它极大地方便了编程人员在不会分布式并行编程的情况下,将自己的程序运行在分布式系统上。 当前的软件实现是指定一个Map(映射)函数,用来把一组键值对映射成一组新的键值对,指定并发的Reduce(归约)函数,用来保证所有映射的键值对中的每一个共享相同的键组。
定义:
MapReduce是面向大数据并行处理的计算模型、框架和平台,它隐含了以下三层含义:
1)MapReduce是一个基于集群的高性能并行计算平台(Cluster Infrastructure)。它允许用市场上普通的商用服务器构成一个包含数十、数百至数千个节点的分布和并行计算集群。
2)MapReduce是一个并行计算与运行软件框架(Software Framework)。它提供了一个庞大但设计精良的并行计算软件框架,能自动完成计算任务的并行化处理,自动划分计算数据和计算任务,在集群节点上自动分配和执行任务以及收集计算结果,将数据分布存储、数据通信、容错处理等并行计算涉及到的很多系统底层的复杂细节交由系统负责处理,大大减少了软件开发人员的负担。
3)MapReduce是一个并行程序设计模型与方法(Programming Model & Methodology)。它借助于函数式程序设计语言Lisp的设计思想,提供了一种简便的并行程序设计方法,用Map和Reduce两个函数编程实现基本的并行计算任务,提供了抽象的操作和并行编程接口,以简单方便地完成大规模数据的编程和计算处理 [1] 。
主要功能:
MapReduce提供了以下的主要功能:
1)数据划分和计算任务调度:
系统自动将一个作业(Job)待处理的大数据划分为很多个数据块,每个数据块对应于一个计算任务(Task),并自动 调度计算节点来处理相应的数据块。作业和任务调度功能主要负责分配和调度计算节点(Map节点或Reduce节点),同时负责监控这些节点的执行状态,并 负责Map节点执行的同步控制。
2)数据/代码互定位:
为了减少数据通信,一个基本原则是本地化数据处理,即一个计算节点尽可能处理其本地磁盘上所分布存储的数据,这实现了代码向 数据的迁移;当无法进行这种本地化数据处理时,再寻找其他可用节点并将数据从网络上传送给该节点(数据向代码迁移),但将尽可能从数据所在的本地机架上寻 找可用节点以减少通信延迟。
3)系统优化:
为了减少数据通信开销,中间结果数据进入Reduce节点前会进行一定的合并处理;一个Reduce节点所处理的数据可能会来自多个 Map节点,为了避免Reduce计算阶段发生数据相关性,Map节点输出的中间结果需使用一定的策略进行适当的划分处理,保证相关性数据发送到同一个 Reduce节点;此外,系统还进行一些计算性能优化处理,如对最慢的计算任务采用多备份执行、选最快完成者作为结果。
4)出错检测和恢复:
以低端商用服务器构成的大规模MapReduce计算集群中,节点硬件(主机、磁盘、内存等)出错和软件出错是常态,因此 MapReduce需要能检测并隔离出错节点,并调度分配新的节点接管出错节点的计算任务。同时,系统还将维护数据存储的可靠性,用多备份冗余存储机制提 高数据存储的可靠性,并能及时检测和恢复出错的数据。
二。代码
mapreduce主要由map(映射)和reduce组成
package com.huhu.day01; import java.io.IOException; import org.apache.hadoop.conf.Configuration; 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.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; /** * word count * * @author huhu_k * */ public class MyWordCount1 { /** * map:映射 * * LongWritable key:指针偏移量。 Text value:每个key对应得value即文本内容 * * 一个文本不管多大 一个mapper 一个快对应一个mapper程序 * * @author huhu_k * */ public static class MyMapper extends Mapper<LongWritable, Text, Text, IntWritable> { /* * (non-Javadoc) * * @see org.apache.hadoop.mapreduce.Mapper#map(KEYIN, VALUEIN, * org.apache.hadoop.mapreduce.Mapper.Context) LongWritable key:指针偏移量。 Text * value:每个key对应得value即文本内容 map中context中的存储内容:Text(文本内容), IntWritable(文本所出现的次数) */ @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { // 数据切割方式(文本中的内容) String[] data = value.toString().split(" "); for (String s : data) { // k:word v:1 context.write(new Text(s), new IntWritable(1)); } } } /** * reduce 计算 * * map输出的kv 就是reduce的输入kv 写一个reducer 类 有几个key,写几个reduce方法 * * @author huhu_k * */ public static class MyReducer extends Reducer<Text, IntWritable, Text, IntWritable> { int sum = 0; @Override protected void reduce(Text key, Iterable<IntWritable> value, Context context) throws IOException, InterruptedException { for (IntWritable v : value) { sum += v.get(); } context.write(key, new IntWritable(sum)); } } public static void main(String[] args) throws Exception { // 配置容器 Configuration conf = new Configuration(); // 创建一个job @SuppressWarnings("deprecation") Job job = new Job(conf, "MyMapReduce Two"); // 配置job job.setJarByClass(MyWordCount1.class); job.setMapperClass(MyMapper.class); job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(IntWritable.class); job.setReducerClass(MyReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); // 输入输出 FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); //执行程序 boolean waitForCompletion = job.waitForCompletion(true); System.exit(waitForCompletion ? 0 : 1); } }
将代码打成jar包上传至hadoop 。输入命令在hadoop种运行
hadoop jar mapreduce.jar /in/ihaveadream.txt /out/2
运行完后
我这里是使用集群运行,没有安装装插件。将类打成jar包,以及类想关联的jar包,然后上传到hadoop种然后运行。