39

这是一个涉及 Hadoop/HDFS 的概念性问题。假设您有一个包含 10 亿行的文件。为了简单起见,让我们考虑每一行的形式<k,v>,其中 k 是行距开头的偏移量, value 是行的内容。

现在,当我们说要运行 N 个映射任务时,框架是否将输入文件拆分为 N 个拆分并在该拆分上运行每个映射任务?或者我们是否必须编写一个分区函数来进行 N 次拆分并在生成的拆分上运行每个映射任务?

我想知道的是,拆分是在内部完成还是我们必须手动拆分数据?

更具体地说,每次调用 map() 函数时,它的Key key and Value val参数是什么?

谢谢,迪帕克

4

10 回答 10

25

InputFormat负责提供拆分。

一般来说,如果你有 n 个节点,HDFS 会将文件分发到所有这 n 个节点上。如果你开始一个工作,默认会有 n 个映射器。感谢 Hadoop,机器上的映射器将处理存储在该节点上的部分数据。我想这叫做Rack awareness.

长话短说:在 HDFS 中上传数据并启动 MR Job。Hadoop 将关心优化的执行。

于 2010-05-14T13:37:14.040 回答
14

文件被拆分为 HDFS 块并复制这些块。Hadoop 根据数据局部性原则为拆分分配一个节点。Hadoop 将尝试在块所在的节点上执行映射器。由于复制,有多个这样的节点托管同一个块。

如果节点不可用,Hadoop 将尝试选择最接近承载数据块的节点的节点。例如,它可以选择同一机架中的另一个节点。一个节点可能由于各种原因不可用;所有地图槽可能正在使用中,或者节点可能只是关闭了。

于 2011-04-22T13:50:27.463 回答
10

幸运的是,一切都将由框架处理。

MapReduce数据处理是由这种输入拆分概念驱动的。为特定应用程序计算的输入拆分数量决定了映射器任务的数量。

映射的数量通常由输入文件中 DFS 块的数量决定。

在可能的情况下,这些映射器任务中的每一个都被分配给存储输入拆分的从节点。资源管理器(或 JobTracker,如果您在 Hadoop 1 中)尽最大努力确保在本地处理输入拆分。

如果由于输入拆分跨越数据节点的边界而无法实现数据局部性,则一些数据将从一个数据节点传输到另一个数据节点。

假设有 128 MB 的块,最后一条记录不适合块 a并在块 b中传播,那么块 b 中的数据被复制到具有块 a 的节点

看看这张图。

在此处输入图像描述

查看相关问题

关于 Hadoop/HDFS 文件拆分

Hadoop 进程记录如何跨块边界拆分?

于 2015-12-13T04:05:27.097 回答
7

我认为 Deepak 所问的更多是关于如何确定每次调用map 函数的输入,而不是每个 map node上存在的数据。我是基于问题的第二部分说的: 更具体地说,每次调用 map() 函数时,它的 Key key 和 Value val 参数是什么?

实际上,同样的问题把我带到了这里,如果我是一位经验丰富的 hadoop 开发人员,我可能会像上面的答案一样解释它。

要回答这个问题,

根据我们为InputFormat设置的值,拆分给定地图节点处的文件。(这是在 java 中使用setInputFormat()完成的!)

一个例子:

conf.setInputFormat(TextInputFormat.class); 在这里,通过将 TextInputFormat 传递给 setInputFormat 函数,我们告诉 hadoop 将map 节点处输入文件的每一行视为 map 函数的输入。换行或回车用于表示行结束。更多信息在TextInputFormat

在此示例中:键是文件中的位置,值是文本行。

希望这可以帮助。

于 2015-03-19T20:53:26.007 回答
4

块大小和输入拆分大小之间的差异。

Input Split 是数据的逻辑拆分,主要用于 MapReduce 程序中的数据处理或其他处理技术。输入拆分大小是用户定义的值,Hadoop 开发人员可以根据数据的大小(您正在处理的数据量)选择拆分大小。

Input Split 主要用于控制 MapReduce 程序中 Mapper 的数量。如果您没有在 MapReduce 程序中定义输入拆分大小,那么在数据处理过程中,默认的 HDFS 块拆分将被视为输入拆分。

例子:

假设您有一个 100MB 的文件,HDFS 默认块配置为 64MB,那么它将被分成 2 个拆分并占用两个 HDFS 块。现在您有一个 MapReduce 程序来处理此数据,但您没有指定输入拆分,然后基于块数(2 个块)将被视为 MapReduce 处理的输入拆分,并且将为该作业分配两个映射器。但是假设,您在 MapReduce 程序中指定了拆分大小(例如 100MB),那么两个块(2 个块)将被视为 MapReduce 处理的单个拆分,并且将为该作业分配一个 Mapper。

现在假设,您已经在 MapReduce 程序中指定了拆分大小(例如 25MB),那么 MapReduce 程序将有 4 个输入拆分,并且将为该作业分配 4 个 Mapper。

结论:

  1. Input Split 是输入数据的逻辑划分,HDFS block 是数据的物理划分。
  2. 如果未通过代码指定输入拆分,则 HDFS 默认块大小是默认拆分大小。
  3. 拆分是用户定义的,用户可以在他的 MapReduce 程序中控制拆分大小。
  4. 一个拆分可以映射到多个块,一个块可以有多个拆分。
  5. 映射任务(Mapper)的数量等于输入分割的数量。

来源:https ://hadoopjournal.wordpress.com/2015/06/30/mapreduce-input-split-versus-hdfs-blocks/

于 2017-08-15T07:21:57.517 回答
1

FileInputFormat是定义如何读取和溢出输入文件的抽象类。FileInputFormat 提供以下功能: 1. 选择应用作输入的文件/对象 2. 定义将文件分解为任务的输入拆分。

根据 hadoopp 的基本功能,如果有 n 个拆分,那么将有 n 个映射器。

于 2013-11-25T08:05:18.590 回答
1

当一个 Hadoop 作业运行时,它将输入文件拆分为块,并将每个拆分分配给一个映射器进行处理;这称为 InputSplit。

于 2016-08-01T11:56:27.410 回答
0

简短的回答是 InputFormat 负责文件的拆分。

我处理这个问题的方法是查看它的默认 TextInputFormat 类:

所有 InputFormat 类都是 FileInputFormat 的子类,它们负责拆分。

具体来说,FileInputFormat 的 getSplit 函数从 JobContext 中定义的文件列表生成 InputSplit 列表。拆分基于字节大小,其Min和Max可以在项目xml文件中任意定义。

于 2013-11-20T22:37:51.013 回答
0

有一个单独的 map reduce 作业将文件分成块。对大文件使用 FileInputFormat,对小文件使用 CombineFileInput Format。您还可以通过 issplittable 方法检查输入是否可以拆分为块。然后将每个块馈送到数据节点,在该数据节点上运行 map reduce 作业以进行进一步分析。块的大小取决于您在 mapred.max.split.size 参数中提到的大小。

于 2014-03-19T09:43:41.173 回答
0

FileInputFormat.addInputPath(job, new Path(args[0])); 或者

conf.setInputFormat(TextInputFormat.class);

FileInputFormat函数 addInputPath,setInputFormat负责 输入拆分,此代码还定义了创建的映射器的数量。我们可以说输入分割和映射器的数量与用于在 HDFS 上存储输入文件的块数成正比。

前任。如果我们有大小为 74 Mb 的输入文件,该文件以两个块(64 MB 和 10 Mb)存储在 HDFS 上。所以这个文件的inputsplit是两个,并且创建了两个映射器实例来读取这个输入文件。

于 2015-07-01T10:49:54.340 回答