【问题标题】:How does Hadoop perform input splits?Hadoop 如何执行输入拆分?
【发布时间】:2011-02-19 08:44:54
【问题描述】:

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

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

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

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

谢谢, 迪帕克

【问题讨论】:

    标签: hadoop mapreduce hdfs


    【解决方案1】:

    InputFormat 负责提供拆分。

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

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

    【讨论】:

    • 一台机器上的映射器是也访问其他机器上的数据还是只处理它机器上的数据?
    • Hadoop 站点上的默认字数统计示例,不使用 InputFormat。如果我在该示例中调用 n 个地图任务会发生什么。每个地图任务都访问文件中的所有内容?再次感谢。
    • 首先,感谢您的投票:-) --- wordcount 示例使用了TextInputFormat,它应该是InputFormat 的子类。 --- 由于拆分的数量与映射器的数量相匹配,每个映射器将最有可能处理最接近它的数据。当然,他可以访问其他机器,但由于成本原因而避免这样做。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

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

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

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

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

      假设有 128 MB 的块,最后一条记录不适合 块 a 并在 块 b 中传播,然后 块 b 中的数据> 将被复制到具有 Block a

      的节点

      看看这张图。

      查看相关问题

      About Hadoop/HDFS file splitting

      How does Hadoop process records split across block boundaries?

      【讨论】:

        【解决方案4】:

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

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

        回答问题,

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

        一个例子:

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

        在这个例子中: 键是文件中的位置,值是文本行。

        希望这会有所帮助。

        【讨论】:

          【解决方案5】:

          块大小和输入分割大小的区别。

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

          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. 输入拆分是输入数据的逻辑划分,而 HDFS 块是数据的物理划分。
          2. 如果未通过代码指定输入拆分,则 HDFS 默认块大小是默认拆分大小。
          3. 拆分是用户定义的,用户可以在其 MapReduce 程序中控制拆分大小。
          4. 一个拆分可以映射到多个块,一个块可以有多个拆分。
          5. 映射任务 (Mapper) 的数量等于输入拆分的数量。

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

          【讨论】:

            【解决方案6】:

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

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

            【讨论】:

              【解决方案7】:

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

              【讨论】:

                【解决方案8】:

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

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

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

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

                【讨论】:

                  【解决方案9】:

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

                  【讨论】:

                    【解决方案10】:

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

                    conf.setInputFormat(TextInputFormat.class);

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

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

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2015-12-14
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多