MapReduce MapReduce,是hadoop中集群数据处理的核心,主要分为映射和减速两部分,映射就是Map部分,减速就是说的Reduce阶段。
Map,就是映射阶段,在数据处理的初期,hadoop会从HDFS中获取要处理的数据,一般处理的数据是文件或者目录,并逐行或逐个的读取,可以通过编程实现Map接口来自己处理映射阶段的数据处理。 Reduce,减速阶段,分为Shuffling和Reducer,主要是处理Map阶段后的数据,处理完成后,产生新的输出,输出到HDFS中,可以通过实现Reduce接口来处理减速器数据的输出。 在MapReduce阶段,输入的值都是键-值对的形式,在实际开发中,需要实现Map和Reduce接口中Map和Reduce方法。 Mapper任务(分割及映射) 输入拆分-Input Splits 映射的第一阶段是将数据进行拆分,如上输入了一个文本,hadoop会把数据分成若干个大小相同的数据块,这些数据块被称为Input Splits,hadoop会根据生成的若干个数据块来生成同样个数的映射任务,可以通过Job.setInputFormat(Class)指定要输入的数据块的格式。 映射块-Mapping 会将Input Splits映射为中间键值对。映射器会根据每个输入块生成一个对应的映射任务,被映射器处理后输出的数据和映射之前的数据块的格式可以是不同的,当然在映射结束后hadoop也允许0个映射输出。 这一阶段会将每个分割传入到映射函数(map)计算出输出内容,可以通过Job.setMapperClass(Class)方法来指定映射处理器。 经过映射处理后hadoop会根据输出的键来对数据进行联合,hadoop的联合阶段会很麻烦,而且消耗很大,所以可以通过使用Job.setCombinerClass(Class)自己定制联合,以此来节省联合阶段的消耗。联合后会被分组,然后传给减速器来进行最后的输出,可以通过Job.setGroupingComparatorClass(Class)方法来指定数据在分组时的处理过程。 mapping阶段最后的输出一般是很简单的键值对,hadoop也提供了数据压缩,主要是用在数据量过大或者数据格式会影响应用程序等的情况。通过实现CompressionCodec接口,自己指定压缩格式,并通过hadoop的配置来配置相应的压缩格式。 在上面的例子中会计算输入分割单词出现的次数,然后排列成数据列表<单词,出现频率>作为输出。 Note:数据最终的映射个数通常是有输入的大小来决定的。正常的映射个数是每个节点映射器量10-100个,最好的情况是每个映射器都在非常快的时间里处理完数据。尽管如此,但是在处理大数据量时可能会需要非常多的映射个数,比如一个10TB的数据作为输入,但是每个映射块最大能处理128MB,这时会需要82,000个映射。在遇到这种情况时可以通过Configuration.set(MRJobConfig.NUM_MAPS, int),来指定映射个数。 Reducer任务(重排,还原) 经过映射后的输出数据会被排序,然后每个映射器会进行分区。总共的分区数量和映射任务的数量是相同的。可以通过实现自定义的Partitioner来指定哪些数据进入哪个Reducer。 Shuffle 对映射后的数据进行排序,然后输入到Reducer。这个阶段hadoop会根据Http协议来接收到所有映射相关的分区。 Sort hadoop会通过输入的键对所有的Reducer进行分组。Shuffle和Sort阶段是同时进行的,在map数据输出时Reducer就会不停的接收。hadoop会提供异步任务不停的从Map输出到获取到数据,如下图的任务调度器。 Secondary Sort 在对中间键值进行分组时的规则如果不同于在Reducing阶段的,则可以通过Job.setSortComparatorClass(Class)指定比较器。由于Job.setGroupingComparatorClass(Class)可用于控制中间键的分组方式,因此可以结合使用这些键来模拟值的二级排序。 减速-Reducer 在这个阶段会调用reduce方法来对排序后的输出进行处理,这个阶段结束后会将数据写入到HDFS中,并返回一个输出值。 减速器的个数大概是0.95或1.75乘以(< 节点数 > * < 每个节点的最大容器数 >)。正常情况下0.95就已经够用了,对数据会进行非常快的处理。如果考虑到负载集群的执行效率,那么可以考虑1.75,它会充分发挥负载集群的效率。 增加减速器的数量会增加框架的开销,但是会增加负载均衡并降低故障的成本。 当然处理的过程中也允许有0个减速输出。这时映射任务的输出直接会直接进入FileSystem,进入FileOutputFormat.setOutputPath(Job,Path)设置的输出路径。在将映射输出写入FileSystem之前,框架不会对映射输出进行排序。
|