所以这一直让我很困惑。我不确定map-reduce到底是如何工作的,我似乎迷失在确切的事件链中。
我的理解:
我想总结一下,我只是不明白如何正确地重新组合文件以及它导致我的映射归约逻辑失败。
第 3 步称为“随机播放”。 它是地图缩减框架的主要增值之一,尽管对于大型数据集来说它也非常昂贵。该框架对所有映射器输出的完整记录集执行类似于 GROUP BY 操作的操作,然后对每组记录调用缩减器。 回答您的个人问题 3:
3.1。想象一下,您的作业配置为具有 r 总减速器。 该框架将每个映射输出文件分割成 r 块,并将每一块发送到一个减速器任务。 总共有 m 映射器,那就是 mr 飞来飞去的小切片。当特定的reducer收到它需要的所有切片时,它将它们全部合并在一起并按K2键对结果进行排序,然后按该键对运行中的记录进行分组以供单独调用reduce()。 如果存在重复的 K2 键,则该组将大于单例。 事实上,这就是重点。如果您的映射器从未输出相同的键,那么您的算法甚至不需要减少阶段,并且您可以完全跳过昂贵的洗牌。
3.2。执行所有数据移动的负载分布在整个集群中,因为每个减速器任务都知道它想要什么输出,并向每个映射器请求它们。 主节点唯一要做的就是协调,即,告诉每个reducer何时开始拉取映射器输出,监视死节点,并跟踪每个人的进度。
3.3。框架不检查或以任何方式组合Reducer 输出。 无论您有多少个减速器任务(r),您都会获得多少个包含 K3、V3 记录的输出文件。 如果您需要再次组合,请对该输出运行另一个作业。
在阅读此答案之前,请花一些时间阅读有关合并排序(分而治之方法)的内容
这是框架在幕后发生的完整操作
JobTracker 找出 split 的位置,并在靠近 split 的位置生成映射器,局部性的优先级是(1. 数据本地,2. 机架本地,3. 网络跳本地)
Mappers 读取数据(FileInputFormat 提供的 Record Readers)并产生 k1->v1
此数据本地保存到运行映射器的本地文件系统中,这里的技巧是保存在本地文件系统上的数据是“排序的”并存储在分区中(等于减速器的数量)
5 .每个reducer从其相应分区的mappers中提取数据(不要忘记reducer拉取的所有数据都是排序的)
{
k1->v1
k1->v2
K2->v3
}
Reducer 打开文件指针,指向从映射器中拉出的所有排序文件并合并它们。 (合并时使用分组和排序比较器)由于合并是从排序的文件中进行的,因此reducer的输出被排序并保存到hdfs上
这一步有点类似于归并排序的“合并步骤”