我们知道,在Hadoop的复制阶段,每个reduce工作进程从所有映射器节点读取数据,并执行已排序数据的合并(在映射器端的内存中排序期间排序)并处理它们的键份额及其值。
现在,我们还知道与特定对应的所有数据将只转到一个化简器。
我的问题是:如何将数据拆分传输到化简器,即分区大小是如何决定的,以及当数据使用拉动机制而不是推送机制传输时,它是由什么过程决定的。这里要应对的一个有趣的挑战是确定数据的总体大小,因为数据驻留在多个节点上(我猜作业跟踪器/主进程可能知道所有节点的数据大小和位置,但我也不确定)。
如果数据高度偏斜并且大部分数据属于有 10 个或更多化简器的单个键,那么在并行处理方面不会降低性能吗?在这种情况下,只有一个化简器进程将以顺序方式处理大部分数据。这种情况在Hadoop中处理吗?如果是,如何?
如何将数据拆分传输到化简器,即分区大小是如何决定的,以及当数据使用拉取机制而不是推送机制传输时,它是由什么过程决定的。这里要应对的一个有趣的挑战是确定数据的总体大小,因为数据驻留在多个节点上(我猜作业跟踪器/主进程可能知道所有节点的数据大小和位置,但我也不确定)。
将数据拆分为分区由 Partitioner 抽象类中存在的 getPartition(KEY k, VALUE v, int numOfReducers) 中编写的逻辑控制。默认的Hadoop分区程序是HashPartitioner。该行为是利用键的 Object.hashCode() 方法,并对 numOfPartition 执行模数。如果您发现 HashPartitioner 在您的情况下效率不高,您可以编写您的分区程序。
当地图任务成功完成时,它们会通知其父任务跟踪器状态更新,而任务跟踪器又会通知作业跟踪器。这些通知通过检测信号通信机制传输。这就是一切保持同步的方式。
如果数据高度偏斜并且大部分数据属于有 10 个或更多化简器的单个键,那么在并行处理方面不会降低性能吗?在这种情况下,只有一个化简器进程将以顺序方式处理大部分数据。这种情况在Hadoop中处理吗?如果是,如何?
是的。这是真的。MapReduce框架提供了不同类型的分区程序,你可以根据自己的要求选择:
- 哈希分区程序
- ,默认分区程序
- TotalOrderPartitioner.它提供了一种按范围分区的方法
- KeyFieldBasedPartitioner.分区程序提供了一种按键部分对数据进行分区的方法。
如果你仍然不满意,你可以实现你自己的逻辑。如果您需要有关如何编写自定义分区程序的一些帮助,请参阅此内容。
呵呵
PS:我不太明白你第一个问题的第二部分。如果答案不清楚或您需要任何进一步的澄清,请告诉我。