3

我有一个有 8 个节点的集群设置,我正在使用 mapreduce 解析一个 20GB 的文本文件。通常,我的目的是通过映射器获取每一行并使用一个键发送,该键是输入文件行上的列之一。reducer 拿到后,会根据 key 值写入不同的目录。如果我举个例子:输入文件:

test;1234;A;24;49;100

test2;222;B;29;22;22

test2;0099;C;29;22;22

所以这些行会写成这样:

/output/A-r-0001

/output/B-r-0001

/output/C-r-0001

我在 reducer 中使用 MultipleOutputs 对象,如果我使用小文件,一切正常。但是当我使用 20GB 文件时,正在初始化 152 个映射器和 8 个减速器。在 mapper 端,一切都很快完成,但一个 reducer 继续运行。7 个减速器完成最多 18 分钟,但最后一个需要 3 小时。首先,我怀疑那个减速器的输入比其他的要大,但事实并非如此。一个减速器的输入是慢速器的三倍,并且在 17 分钟内完成。

我也尝试将 reducer 的数量增加到 14 个,但这是因为减少了 2 个更慢的 reduce 任务。

我检查了很多文档,但不知道为什么会这样。你们能帮我吗?

已编辑

问题是由于我的数据集中的一些损坏的数据。我已经对映射器端的输入数据进行了一些严格的检查,现在它工作正常。

多谢你们。

4

3 回答 3

6

我已经看到在处理倾斜数据时经常发生这种情况,所以我最好的猜测是您的数据集是倾斜的,这意味着您Mapper将发出许多具有相同键的记录,这些记录将进入同一个减速器,因为它有很多价值观要经历。

对此没有简单的解决方案,它实际上取决于您工作的业务逻辑,您可能会检查一下Reducer并说如果您有超过 N 个值,则忽略 N 之后的所有值。

我还找到了一些关于SkewReduce的文档,它应该可以更容易地在他们的论文中描述的 Hadoop 环境中管理倾斜数据,但我自己还没有尝试过。

于 2013-05-30T16:42:26.200 回答
0

这是慢速运行减速器和快速运行减速器的计数器

task_201403261540_0006_r_000019 运行速度非常慢,而 task_201403261540_0006_r_000000 完成速度非常快

很明显,我的一个减速器正在获得大量的键。我们需要优化我们的自定义分区器

在此处输入图像描述

在此处输入图像描述

于 2014-03-27T13:06:57.500 回答
0

感谢您的解释。我知道我的数据集没有均匀分布的键值对。下面是我使用 14 个 reducer 和 152 个映射器的测试之一。

完成 17 分 27 秒的任务

文件系统计数器

FILE_BYTES_READ 10,023,450,978

FILE_BYTES_WRITTEN 10,023,501,262

HDFS_BYTES_WRITTEN 6,771,300,416

Map-Reduce 框架

减少输入组 5

合并输出记录 0

减少 shuffle 字节 6,927,570,032

减少输出记录 0

泄露记录 28,749,620

合并输入记录 0

减少输入记录 19,936,319

完成 14 小时 17 分 54 秒的任务:

文件系统计数器

FILE_BYTES_READ 2,880,550,534

FILE_BYTES_WRITTEN 2,880,600,816

HDFS_BYTES_WRITTEN 2,806,219,222

Map-Reduce 框架

减少输入组 5

合并输出记录 0

减少 shuffle 字节 2,870,910,074

减少输出记录 0

泄露记录 8,259,030

合并输入记录 0

减少输入记录 8,259,030

花费这么多时间的记录要经过的记录较少。

除此之外,一段时间后,相同的任务正在从不同的节点初始化。我猜hadoop认为任务很慢并初始化另一个。但这根本没有帮助。

于 2013-05-30T21:04:03.607 回答