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