【发布时间】:2012-05-12 03:39:46
【问题描述】:
我正在尝试对大量数据运行 hadoop 作业,最多使用 32 个减速器。但是当我查看每个减速器的输出时,我发现可能会发生不止一个减速器获得一个键(当然具有不同的值)。在使用更多减速器时可以避免这种行为吗?
LE:我已经尝试并使用了 Text 类,但问题是虽然它工作正常,但我的 jvm 最终由于堆空间不足而崩溃。除了 compareTo 之外,hadoop 用于将数据分区到密钥池中的标准是什么?
【问题讨论】:
我正在尝试对大量数据运行 hadoop 作业,最多使用 32 个减速器。但是当我查看每个减速器的输出时,我发现可能会发生不止一个减速器获得一个键(当然具有不同的值)。在使用更多减速器时可以避免这种行为吗?
LE:我已经尝试并使用了 Text 类,但问题是虽然它工作正常,但我的 jvm 最终由于堆空间不足而崩溃。除了 compareTo 之外,hadoop 用于将数据分区到密钥池中的标准是什么?
【问题讨论】:
您说您有一个自定义键(实现 WritableComparable),您是否重写了 hashCode() 方法?
如果您使用的是 HashPartitioner(这是默认设置),并且没有覆盖自定义键中的 hashCode() 方法,那么来自不同映射器的两个相同键很可能会转到不同的减速器(结果hashCode() 与 reducer 的数量取模,以确定将键/值对发送到的 reducer)。这是因为默认情况下 hashCode() 方法是原生的,并返回对象在内存中的地址
键的简单 hashCode 实现可以像将元组字段的 hashcode 添加在一起一样简单(假设这些字段本身具有非本地 hashCode 实现):
public int hashCode() {
return field1.hashCode() + field2.hashCode()
}
【讨论】:
我怀疑您看到的是投机执行。通常,给定键的所有值总是恰好到达一个减速器。来自http://developer.yahoo.com/hadoop/tutorial/module4.html:
推测执行:Hadoop 系统的一个问题是,通过将任务划分到多个节点上,可能会导致一些慢 节点对程序的其余部分进行速率限制。例如,如果一个节点 有一个慢速磁盘控制器,那么它可能只读取它的输入 所有其他节点速度的 10%。所以当99个地图任务已经 完成,系统还在等待最后的地图任务检查 in,这比所有其他节点花费的时间要长得多。
通过强制任务彼此隔离运行,个人 任务不知道他们的输入来自哪里。任务信任 Hadoop 平台只提供适当的输入。因此,同样 输入可以并行处理多次,以利用 机器能力的差异。由于工作中的大多数任务是 即将结束,Hadoop平台将调度冗余副本 跨几个没有其他任务的节点的剩余任务 工作来执行。这个过程被称为推测执行。什么时候 任务完成后,他们向 JobTracker 宣布这一事实。任何 任务的副本首先完成成为最终副本。如果其他 副本是推测性执行的,Hadoop 告诉 TaskTracker 放弃任务并丢弃它们的输出。然后减速器收到 无论哪个 Mapper 成功完成他们的输入,首先。
默认情况下启用推测执行。 您可以禁用 通过设置 mapred.map.tasks.speculative.execution 和 mapred.reduce.tasks.speculative.execution JobConf 选项为 false, 分别。
【讨论】: