考虑以下问题:
编辑:如果下面的算法没有太大意义,请忽略。我只是为了它而把它放在那里。这个想法是doFunc
是某种递归的。
doFunc(A):
[a0, a1, a2, ...] <- A
If (someCondition([a0, a1, a2, ...]) == False)
A <- modified(A)
r = doFunc(modified(A))
A <- convertR(r)
B <- someFunc1(A)
C <- someFunc2(B)
r <- lastFunc(D)
return r
在这种情况下,r是递归函数
doFunc
的结果,其中a0, a1, a2, ...
列表上的someCondition为false
,该函数递归以获得某种条件为A
的最佳true
。现在考虑将MapReduce分别应用于程序的不同部分-例如,将
A
转换为a0, a1, a2, ...
,然后先使用MapReduce来获取modifiedA
和someFuncI
,那么递归如何适合此MapReduce实现?考虑到这一点,考虑到我不了解如何使用递归来实现,Hadoop Streaming根本无法解决。唯一的其他可能性是执行某种形式的Python Hadoop Streaming Wrapper,例如
dumbo
或mrjob
来编写代码,而忽略了递归,当递归调用doFunc
时,递归显然会展开。我想知道MapReduce的影响因素以及可扩展性如何。问题:我已经问过上面文本中的问题,但是它们可能不够清楚。所以我将它们放在这里。
最佳答案
可以在Hadoop中实现的唯一形式的递归是尾递归,这意味着递归调用必须在当前调用的末尾进行。严格来说,递归根本无法在Hadoop中进行仿真,因为该框架无法在执行下一个(递归调用)时保存当前作业的状态,然后重新加载当前作业并恢复其执行。但是,可以通过链接作业来模拟尾递归,即当一个端点开始下一个端点时。
我已经成功地链接了数十/数百个工作。因此,按顺序融合几个(可能甚至数千个)作业没有特别的问题。但是,由于以下三个主要原因,与该做法相关的性能损失:设置/删除作业需要时间,作业可能失败并且需要重新启动,作业的计算机速度可能较慢,从而延迟了该作业的终止。
但是,除了这些细节之外,我认为您应该做的是确保Hadoop是您所需要的。从某种意义上说,Hadoop是一个非常专业的框架,它可以处理“可数据并行化”的任务,即可以(通常)处理大数据的任务,并且可以一次应用于整个数据集,也可以重复应用于这些数据的小块最后,获得与应用于整个数据集相同的结果。您所描述的似乎不属于此类。