MapReduce中为什么需要Input Splits?【翻译】

本文解释了,为什么在Mapreduce中的Mapper阶段处理数据是以输入分片为基本单元。本文是译文,如有翻译不妥的地方,敬请指正!

http://my.oschina.net/gooke/blog/403656

HDFS会把非常大的文件分割成多个大的数据块(例如,128M),并且每一个数据块在集群的不同节点上存储3个备份。HDFS并不知道也不关心这些文件的内容。

在yarn上,当一个Mapreduce任务开始时,Resource Manager(负责集群的资源管理和任务调度)会创建一个Application Master守护进程来监视这个任务的生命周期。

(在Hadoop1中,JobTracker监控每个Mapreduce任务,以及作业的调度和集群资源的管理)

AM(Application Master,下同)首先要做的事情是确定任务所需要的数据块。AM向NameNode询问所需要的数据块的副本的存储位置。带着这些文件数据块本地化信 息,AM向资源管理器(Resource Manager)发出请求,资源管理器会在数据块所在的从节点(Slave Node)上产生一个Mapper任务来处理数据块。

MapReduce任务高效工作的关键是数据处理本地化,即在存储数据块的从节点上处理数据。

译者注:这就是所谓的"数据本地化优化",因为它无需使用宝贵的集群带宽资源。

在知道数据块怎么被处理之前,你要先知道Hadoop是怎么存储数据的。在Hadoop中,文件由每条独立的记录组成,最终被Mapper任务逐条记录的处理。

例如,示例数据集中包含了美国1987年至2008年所有已完成航班的信息。

示例数据集下载地址:http://stat-computing.org/dataexpo/2009/the-data.html

示例数据集格式:

每一年都有一个非常大的文件,在每个文件中,每一行代表了一次航班。换言之,一行代表了一条记录。

现在,假设Hadoop集群的数据块大小是64M,这就意味着这些航班数据文件会被分割成多个精确的64M大小的数据块。

那么问题来了?如果每一个Mapper任务要处理指定数据块中的所有记录,那么这些记录在跨越不同数据块边界时会发生什么?文件数据块是精准的64M(或者任何你设置的大小),但是因为HDFS不知道数据块中存储的内容,当一条完成的记录被划分到了不同的数据块中,它也不会知道。

译者注:HDFS在分割数据块时会精准到字节,一个数据块是64M,多一个或少一个字节都不行。而文件是由每一条完整的记录组成,所以HDFS在把大文件分割成多个数据块时,有可能会把一条完整的记录划分到不同的数据块中。

当在一个数据块中的最后一条记录不完整的情况下,输入分片(input split)中就会包含下一个数据块的储存信息以及最后一条记录的剩余数据的字节偏移量。

下面这张图表示了数据块和输入分片两者的关系。

你可以通过配置,让AM守护进程(或者Hadoop1中的JobTracker)去计算输入分片而不是任务客户端,这样Mapper在处理大量数据块时会快一些。

MapReduce 处理数据是基于输入分片的。一个应用中的输入分片的数量决定了Mapper任务的数量。如果可能的话,每个Mapper任务被分配在输入分片所在的从节点 上。Resource Manager(或者,Hadoop1中的JobTracker)尽量让输入分片在本地被处理。

原文:http://www.dummies.com/how-to/content/input-splits-in-hadoops-mapreduce.html

  1. da shang
    donate-alipay
               donate-weixin weixinpay

发表评论↓↓