MapReduce原理及编程
什么是mapreduce
map 数据映射
reduece 计算 把映射好的数据整合到一起
- MapReduce是一个分布式计算框架
它将大型数据操作作业分解为可以跨服务器集群并行执行的单个任务。 - 适用于大规模数据处理场景
每个节点处理存储在该节点的数据 - 每个job包含Map和Reduce两部分
MapReduce的设计思想
- 分而治之
简化并行计算的编程模型 - 构建抽象模型:Map和Reduce
开发人员专注于实现Mapper和Reducer函数 - 隐藏系统层细节
开发人员专注于业务逻辑实现
MapReduce特点
- 优点
- 易于编程
- 可扩展性
- 高容错性
- 高吞吐量
- 不适用领域(缺点)
- 难以实时计算
- 不适合流式计算
MapReduce编程模型
MapReduce执行过程
- 数据定义格式
map: (K1,V1) → list (K2,V2)
reduce: (K2,list(V2)) → list (K3,V3) - MapReduce执行过程
Mapper
Combiner 进行合并
Partitioner 进行重新分区
Shuffle and Sort 排序
Reducer 进行计算
Hadoop V1 MR引擎
- Job Tracker
1.运行在Namenode
2.接受客户端Job请求
3.提交给Task Tracker - Task Tracker
1.从Job Tracker接受任务请求
2.执行map、reduce等操作
3.返回心跳给Job Tracker
Hadoop V2 YARN
Hadoop2 MR在Yarn上运行流程
InputSplit(输入分片)
输入分片存储的并非数据本身,而是一个分片长度和一个记录数据的位置的数组,每个输入分片对应一个Mapper任务,所以Mapper的数量是无法指定的。
Shuffle阶段
Shuffle阶段是指数据从Map输出到Reduce输入的过程
Key&Value类型
- 必须可序列化(serializable)
作用:网络传输以及持久化存储
IntWritable、LongWriteable、FloatWritable、Text、DoubleWritable, BooleanWritable、NullWritable等 - 都继承Writable接口
并实现write()和readFields()方法 - Keys必须实现WritableComparable接口
Reduce阶段需要sort
keys需要可比较
InputFormat接口
Combiner类
Combiner相当于本地化的Reduce操作
在shuffle之前进行本地聚合
用于性能优化,可选项
输入和输出类型一致
Reducer可以被用作Combiner的条件
符合交换律和结合律
实现Combiner
job.setCombinerClass(WCReducer.class)
Partitioner类
用于在Map端对key进行分区
默认使用的是HashPartitioner
获取key的哈希值
使用key的哈希值对Reduce任务数求模
决定每条记录应该送到哪个Reducer处理
自定义Partitioner
继承抽象类Partitioner,重写getPartition方法
job.setPartitionerClass(MyPartitioner.class)
OutputFormat接口
编写M/R Job(格式固定)
InputFormat
Job job = Job.getInstance(getConf(), "WordCount" );
job.setJarByClass( getClass() );
FileInputFormat.addInputPath(job, new Path(args[0]) );
job.setInputFormatClass( TextInputFormat.class );
OutputFormat
FileOutputFormat.setOutputPath( job, new Path(args[1]) );
job.setOutputFormatClass( TextOutputFormat.class );
Mapper
job.setMapperClass( WCMapper.class );
job.setMapOutputKeyClass( Text.class );
job.setMapOutputValueClass( IntWritable.class );
Reducer
job.setReducerClass( WCReducer.class );
job.setOutputKeyClass( Text.class );
job.setOutputValueClass( IntWritable.class );
使用MapReduce实现WordCount
原理图:
- 编写Java代码
Mapper
Reducer
Job - 执行M/R Job
- hadoop jar jar包名称 jar包中驱动(Driver)路径 hdfs中文件全路径 hdfs中输出结果路径.
- 设置M/R参数
1.编写mapper
public class WCMapper extends Mapper<LongWritable, Text,Text, IntWritable> {
@Override
protected void map(LongWritable key, Text value, Context context)