MapReduce 简介
说明: 通过由普通机器组成的集群对大量数据集进行并行处理可依靠的容错软件框架。
MapReduce作业可以将数据集分割为Map任务并行处理的数据块,框架对对Map过程产生的数据进行排序,然后最为reduce任务的数据输入,通常作业的的输出和输入数据保存在一个文件系统(Spark通常保存在内存),框架主要关注点在任务调度,任务监控,执行失败任务。
通常计算节点和存储节点是相同的,也就是Mapreduce框架和HDFS在同一组DataNode运行,这种配置可以允许框架在集群高效调度任务,从而避免因为节点之间的数据传输造成宽带的浪费以及效率的降低
数据靠近原则:运行任务以及执行任务需要的数据最好在同一台机器,这样任务执行过程中涉及到的数据可以提供类似本地访问的方式处理,从而提高效率
MapReduce组件
MapReduce框架有一个主ResourceManager,集群节点的NodeManager以及每个应用匹配的MRAppMaster组成,也就是一个MapReduce只有一个ResourceManager,但是可以有许多个NodeManger,并且一个作业只对应一个MRAppMaster(hadoop 2.x使用YARN作为资源管理器)
最低限度应用需要通过抽象类的实现来指定map和reduce的input/output位置,并结合其他的作业参数构成MapReduce任务的配置,Hadoop作业客户端然后提交作业和配置信息给ResourceManager,ResourceManger接收Worker的响应信息,并且调度任务、监控任务、返回作业状态信息给作业客户端,尽管Hadoop框架是由Java实现,MapReduce作业可以不使用Java编写,Hadoop Streaming允许用户使用作为Mapper和Reducer的可执行文件来创建和运行作业,hadoop Pipes是一个兼容C++ API实现的mapReduce应用(非基于JNI)
Inputs and Outputs
MapReduce框架只操作pairs,框架将一组key-value的pair作为作业的输入和输出,输入、输入可以是不同的类型,key和value必须能支持通过网络传输,因此必须序列化,实现Writable接口,为了方便排序则实现WritableComparable接口
mapReduce工作过程
(input) (k1, v1) --> map -->( k2, v2) --> combine --> (k2, v2) --> reduce --> (k3, v3) (output)
Mapper接口:
将框架分割输入数据映射为一组中间key-value对,Map只是将输入记录转换为一个中间记录,转换之后的数据类型不要求和输入类型相同,Hadoop MapReduce为每个由作业的InputFormat生成的InputSplit产生对应的Map任务,总之mapper可以通过作业的Job.setMapperClass(Class)传递给作业,框架然后调用处理任务InputSlipt内部的key-value的map(WritableComparable, Writable, Context)方法,应用可以重写cleanup(Context)方法来执行清理任务。output对不要求和input对的类型一直,output对只要通过context.warite(WritableComparable, Writable)收集,应用同样可以使用Counter来报告它的统计信息。注意所有的中间结果随后都会被框架排序分组,并且传递给Reducer来就决定最终结果,用户可通过Job.setGroupingComparatorClass(Class)方法来指定Comparator来控制分组过程,Mapper输出数据被排序,然后分区给每个Reducer,分区的总数量与作业的reduce作业的数量一致,用户可以在Reducer实现Partitioner接口开控制分区中包含的key,注意Mapper会将Ouput对放在某个位置,Reducer会从对应的位置主动抓取数据。用户可选择的通过 Job.setCombinerClass(Class)来指定一个combiner去执行中间结果的本地聚合,这样有利于减少从Mapper到Reducer的传输数据。中间排序的output总是保存为一个简单的(key-len, key, value-len, value)格式。应用可以通过Configuration控制Output是否压缩、如何压缩。
Mapper数量
Maps的数量是根据input的总大小,也就是输入数据文件的总的数据块数决定,推荐并行执行map过程大约是10-100/单节点,例如输入数据为10T,数据块大小128M,map作业数=1010241024/128 = 81920 个,实际Map作业可能出现失败,也就是最小的,map作业数量是81920,但是可以使用Configuration.set(MRJobConfig.NUM_MAPS, int) 方法设置map的数量
Reducer接口
通过相同的key聚合中间结果(key-valueList),reducer的数量可以通过Job.setNumReduceTasks(int)设置,总之Reducer可以通过Job.setReducerClass(Class)方法传递给作业,在Map分组的key-valueList调用 reduce(WritableComparable, Iterable<Writable>, Context),应用可以通过重写cleanup(Context)方法执行清理任务
reducer分给3个过程:shuffle,sort,reduce
- shuffle: 导入Reducer的是Mappers已排序的输出结果,shuffle主要通过HTTP方式住区所有的Mapper输出的数据分区
- sort: 框架主要根据key对Reducer进行分组,shuffle和sort是同时进行的,Mapper输出会被抓取合并
- Secondary Sort: 如果想要对中间记录实现与在reduce之间的key分组方式不同,可通过Job.setSortComparatorClass(Class) 来设置一个Comparator。Job.setGroupingComparatorClass(Class)用于控制中间记录的分组方式,这些能用来进行值的二次排序。
- reduce: 这个阶段reduce(WritableComparable, Iterable<Writable>, Context)方法被调用,reduce任务结果会通过Context.write(WritableComparable, Writable)写入文件系统,应用可以Counter报告reduce任务的统计信息,Reducer的输出数据是不会排序的
Reducer数量
推荐的数量是node节点数与0.95或1.75的积,0.95d的时候当map完成之后,所有的reduce任务会立即运行并传输map的输出数据,1.75更快的节点会首先完成第一轮的reduce任务,接着发动第二轮的reducer任务,能够起到更好的作业执行的负载均衡的效果。图稿reduce的数量会提高框架的消耗,但是会提高负载均衡和较低失败的概率,缩放因子的reduce数会少于全部的所有redcue任务,因为存在部分reduce处理特殊任务和失败任务
Reducer None
通过设置reducer数量为0,MapReduce只会执行Map过程,并且通过 FileOutputFormat.setOutputPath(Job, Path).方法设置Map的输出数据保存路径,在保存在文件系统之前,map的输出数据不会进行排序
partioner
partioner主要划分key的空间,控制map输出数据的key分区过程,key一般是通过hash函数产生,传给partioner用于构建分区,分区的数量与reduce任务数量相同,默认的分区器:HashPartitioner,hash算法计算ke
counter
Counter是MapReduce应用报告统计信息的工具
作业输入
过程:
- 校验作业数据是否符合规范
- 切分输入文件为逻辑的InputSplit实例,InputSplit被分配给一个map任务
- RecordReader 从InputSplit中读取数据,用于Mapper处理 基于文件的Inputformat基于文件的大小用于切分输入文件为InputSplit实例,fileSystem的输入文件的blockSize视为inputSplit的上限,hadoop2.x 128M,hadoop1.x 64M,可以通过mapreduce.input.fileinputformat.split.minsize来调整MapReduce过程中的blockSize,从而改变map的数量,TextInputFormat 是默认Inputformat
InputSplit
表示一个独立的Mapper处理的数据,FileSplit是默认的InputSplit,可通过设置 mapreduce.map.input.file设置逻辑切分的输入文件路径
RecordReader
从InputSplit读取key-value键值对,用于Map过程处理
作业输出
过程:
- 校验作业输出数据
- RecordWriter 将作业的输出数据写入文件系统TextOutputFormat 是默认的OutputFormat
OutputCommitter
描述一个MapReduce作业的任务提交
- 初始化时设置作业
- 作业完成后清理作业
- 设置任务零食输出
- 检测任务是否需要提交
- 提交任务输出
- 取消任务提交
FileOutputCommitter 是默认的OutputCommitter
RecordWriter
将输出key-value键值对写入输出文件
转载于: