Hadoop 是否根据程序中设置的映射器数量来拆分数据?也就是说,有一个大小为 500MB 的数据集,如果 mapper 的数量是 200 个(假设 Hadoop 集群允许同时有 200 个 mapper),每个 mapper 是否给定 2.5 MB 的数据?
此外,所有映射器是否同时运行或其中一些可能会串行运行?
Hadoop 是否根据程序中设置的映射器数量来拆分数据?也就是说,有一个大小为 500MB 的数据集,如果 mapper 的数量是 200 个(假设 Hadoop 集群允许同时有 200 个 mapper),每个 mapper 是否给定 2.5 MB 的数据?
此外,所有映射器是否同时运行或其中一些可能会串行运行?
反之亦然。映射器的数量是根据拆分的数量决定的。实际上InputFormat
,创建拆分是您正在使用的 的工作。在确定拆分数量之前,您不知道映射器的数量。而且,并不总是会根据 HDFS 块大小创建拆分。这完全取决于getSplits()
InputFormat 方法内部的逻辑。
为了更好地理解这一点,假设您正在使用 MR 处理存储在 MySQL 中的数据。由于在这种情况下没有块的概念,因此始终基于 HDFS 块创建拆分的理论失败了。正确的?那么分裂创作呢?一种可能性是根据 MySQL 表中的行范围创建拆分(这就是这样DBInputFormat
做的,一种用于从关系数据库读取数据的输入格式)。假设您有 100 行。然后你可能有 5 个拆分,每个拆分 20 行。
只有基于FileInputFormat
输入格式(用于处理存储在文件中的数据的输入格式)的 InputFormat,才会根据输入文件的总大小(以字节为单位)创建拆分。但是,输入文件的 FileSystem 块大小被视为输入拆分的上限。如果您有一个小于 HDFS 块大小的文件,您将只获得该文件的 1 个映射器。如果你想有一些不同的行为,你可以使用 mapred.min.split.size。但这又完全取决于您的 InputFormat 的 getSplits()。
split
MR和 HDFS之间存在根本区别block
,人们经常对此感到困惑。块是物理数据,而拆分只是将被馈送到映射器的逻辑块。拆分不包含输入数据,它只是对数据的引用。那么什么是分裂呢?拆分基本上有两件事:一个length in bytes
和一组storage locations
,它们只是主机名字符串。
回到你的问题。Hadoop 允许超过 200 个映射器。话虽如此,仅 500MB 的数据就拥有 200 个映射器并没有多大意义。永远记住,当您谈论 Hadoop 时,您处理的是非常庞大的数据。仅向每个映射器发送 2.5 MB 数据将是一种过度杀伤力。是的,如果没有空闲的 CPU 插槽,那么一些映射器可能会在当前映射器完成后运行。但是 MR 框架非常聪明,并尽力避免这种情况。如果存在要处理数据的机器,但没有任何空闲 CPU 插槽,则数据将被移动到附近有空闲插槽可用的节点并得到处理。
高温高压
当您将数据输入 Hadoop 分布式文件系统 (HDFS) 时,Hadoop 会根据块大小(默认 64 MB)拆分您的数据,并将块分布在整个集群中。所以你的 500 MB 将被分成 8 个块。它不依赖于映射器的数量,它是 HDFS 的属性。
现在,当您运行 MapReduce 作业时,Hadoop 默认为每个块分配 1 个映射器,因此如果您有 8 个块,hadoop 将运行 8 个映射任务。
但是,如果您明确指定映射器的数量(即 200),那么每个 Map 处理的数据大小取决于块的分布,以及您的映射器在哪个节点上运行。有多少映射器实际处理您的数据取决于您的输入拆分。
在您的情况下,假设 500 MB 分成 8 个块,即使您指定 200 个映射器,即使它们已初始化,也不是所有的映射器都会处理数据。
我刚刚根据您的问题运行了一个示例 MR 程序,这是我的发现
输入:小于块大小的文件。
案例 1:映射器数量 =1 结果:启动了 1 个映射任务。每个映射器的输入分割大小(在这种情况下只有一个)与输入文件大小相同。
案例 2:映射器数量 = 5 结果:启动了 5 个映射任务。每个映射器的 Inputsplit 大小是输入文件大小的五分之一。
案例 3:映射器数量 = 10 结果:启动了 10 个映射任务。每个映射器的 Inputsplit 大小是输入文件大小的十分之一。
所以基于上述,对于小于块大小的文件,
拆分大小 = 总输入文件大小 / 启动的地图任务数。
注意:但请记住,没有。地图任务的数量取决于输入拆分。
如果 200 个映射器正在运行 500mb 的数据,那么您需要检查每个单独的文件大小。如果该文件大小小于块大小(64 mb),那么它将为每个文件运行 map 任务。
通常我们将较小的文件合并到大文件中(大小大于块大小)
不,这不对。
作业的映射器数量由框架定义。
看看 Apache MapReduce教程链接。
多少张地图?
映射的数量通常由输入的总大小驱动,即输入文件的总块数。
地图的正确并行度似乎是每个节点大约 10-100 个地图,尽管对于非常 cpu-light 的地图任务,它已设置为 300 个地图。任务设置需要一段时间,因此最好至少花费一分钟来执行地图。
因此,如果您期望 10TB 的输入数据和 128MB 的块大小,那么您最终将得到 82,000 个地图,除非使用 Configuration.set(MRJobConfig.NUM_MAPS, int) (它只为框架提供提示)来设置它甚至更高。
回到您的查询:
也就是说,有一个大小为 500MB 的数据集,如果 mapper 的数量是 200 个(假设 Hadoop 集群允许同时有 200 个 mapper),每个 mapper 是否给定 2.5 MB 的数据?
如果 DFS 块和输入拆分大小为128 MB,则500 MB文件需要4 个 Mapper来处理数据。在上述情况下,框架将运行 4 个 Mapper 任务。
所有映射器是否同时运行,或者其中一些可能会串行运行?
所有映射器同时运行。但是只有当所有 Mapper 的输出都被复制并可供它们使用时,Reducer 才会运行。