0

正如我们所知,在 hadoop 的复制阶段,每个reduce worker 进程从所有mapper 节点读取数据,并对已经排序的数据(在mapper 端的内存排序期间进行排序)进行合并,然后处理它们的共享键及其值。

现在,我们也知道,对应于一个特定的所有数据将只去一个 reducer。

我的问题是:如何将数据拆分传输到reducer,即分区大小是如何决定的,以及它是由什么过程决定的,因为数据是使用拉机制而不是推机制传输的。这里要解决的一个有趣挑战是确定数据的总体大小,因为数据驻留在多个节点上(我猜作业跟踪器/主进程可能知道所有节点的数据大小和位置,但我也不确定)。

如果数据高度倾斜并且大部分数据属于有 10 个或更多 reducer 的单个 key,这不会在并行处理方面造成性能损失。在这种情况下,只有一个 reducer 进程会以顺序方式处理大部分数据。这种情况是否在 Hadoop 中处理?如果是,如何?

4

1 回答 1

3

数据拆分如何传输到reducer,即分区大小是如何决定的,以及它是由什么过程决定的,因为数据是使用拉机制而不是推机制传输的。这里要解决的一个有趣挑战是确定数据的总体大小,因为数据驻留在多个节点上(我猜作业跟踪器/主进程可能知道所有节点的数据大小和位置,但我也不确定)。

将数据拆分为分区由Partitioner抽象类中的getPartition(KEY k, VALUE v, int numOfReducers)内部编写的逻辑控制。默认的 Hadoop 分区器是HashPartitioner。行为是利用键的Object.hashCode()方法并对 numOfPartitions 执行模运算。如果您发现 HashPartitioner 在您的情况下效率不高,您可以编写您的 Partitioner。

随着地图任务成功完成,它们会将状态更新通知其父 TaskTracker,而后者又会通知 JobTracker。这些通知通过心跳通信机制传输。这就是一切保持同步的方式。

如果数据高度倾斜并且大部分数据属于有 10 个或更多 reducer 的单个 key,这不会在并行处理方面造成性能损失。在这种情况下,只有一个 reducer 进程会以顺序方式处理大部分数据。这种情况是否在 Hadoop 中处理?如果是,如何?

是的。是真的。MapReduce 框架提供了不同类型的 Partitioner,您可以根据自己的要求进行选择:

  • HashPartitioner,默认分区器
  • TotalOrderPartitioner。它提供了一种按范围分区的方法
  • KeyFieldBasedPartitioner。Thie partitioner 提供了一种按部分键对数据进行分区的方法。

如果您仍然不满意,您可以实现自己的逻辑。如果您需要有关如何编写自定义分区程序的帮助,请参阅此内容。

高温高压

PS:我不太明白你第一个问题的第二部分。如果答案不明确或您需要进一步澄清,请告诉我。

于 2013-09-11T12:34:06.883 回答