我读了一篇关于MapReduce的文章,但我仍然对如何将任务分成任务(详细)来利用并行处理感到困惑,特别是在这样的情况下:假设Map处理后,我们有1亿条记录(键/值对),有5个键,即'key1', ' key2', 'key3', ' key4', 'key5'。第一个键有9900万条记录,其余的键各有25万条记录。如果我们有3个工人来做减少任务,主如何分配工作?我读到每个键只由一个减速器处理,所以如果一个减速器必须处理'key1',那么它会比其他减速器工作得更多吗?在这种情况下,减速器的并行处理没有多大帮助?
Map reduce技术默认有几个假设:
-
作业不是相互依赖的,即你不必先运行task1来获得它的输出;然后运行task2,输出结果为task1;等。
-
可以将作业划分为在执行能力和时间上"相似"的任务。你的例子是这种假设的极端情况,因此Map-reduce不能很好地工作。
-
存在一种合理的划分策略,这种策略不会比运行任务花费更多的时间。
-
可以并行的任务是任务中的主要工作,它们不依赖于某些串行/单个资源。例如磁盘IO。
在现实中有很多问题满足以上4点(当然有很多不满足,这就是为什么Map-reduce不是一个通用的解决方案)。常见的例子包括所有输入数据量大、需要单独处理、计算时间昂贵但输入数据总量小的问题。例如
-
确定一条线是否与3D结构相交,其中可能有许多三角形面,并对每个三角形运行相交确定
-
大宗金融产品定价
具有相同键的输入数据不必分配给一个reducer。多个reducer可以共享相同key的输入数据。
以合并排序为例。映射作业将一个数组划分为几个子数组。多层reduce作业排序并将这些子数组合并回一个数组。无论数据在数组中如何排列,复杂度仍然是O(n log n)。实际上,在最佳情况和最差情况下,归并排序的复杂度与平均情况是相同的。归并排序算法对数组进行划分和归并的方式不受数据排列的影响