考虑以下问题:
编辑:如果下面的算法没有多大意义,请忽略。我把它放在那里只是为了它。这个想法是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
,该函数递归得到条件为true
的某种最优A
。
现在考虑一下,MapReduce可以单独应用于程序的不同部分——例如,将A
转换为a0, a1, a2, ...
,然后获得modifiedA
,然后再获得someFuncI
——使用MapReduce都是可能的,递归如何适应这个MapReduce实现?
考虑到这一点,Hadoop流是不可能的,因为我不知道如何用递归实现它。唯一的另一种可能性是使用某种形式的Python Hadoop流式包装器(例如dumbo
或mrjob
)编写代码,忽略递归,当递归调用doFunc
时,递归显然会展开。我想知道这是如何与MapReduce相结合的,以及可伸缩性是什么样的。
问题:我已经问了上面文本中的问题,但可能不够清楚。所以我会把它们放在这里。
- MapReduce在递归中表现良好吗
- 如果是,它的规模是否良好
- 有没有一种方法可以用涉及递归的函数来实现Hadoop流
Hadoop中唯一可以实现的递归形式是尾递归,这意味着递归调用必须在当前调用的末尾。严格来说,在Hadoop中根本无法模拟递归,因为框架无法在下一个作业(递归调用)执行时保存当前作业的状态,然后重新加载当前作业并继续执行。然而,尾部递归可以通过链接作业来模拟,即当一个作业结束时开始下一个作业。
我已成功地将数十个/数百个工作岗位链接起来。因此,在一个序列中融合几个(甚至数千个)工作并没有什么特别的问题。然而,由于以下三个主要原因,这种做法会带来性能损失:设置/删除作业需要时间,作业可能会失败并需要重新启动,作业的机器速度可能较慢,从而延迟该作业的终止。
但是,除了这些细节之外,我认为您应该做的是确保Hadoop是您所需要的。Hadoop是一个非常专业的框架,因为它处理"数据可并行"的任务,即处理(通常)大数据的任务,这些任务可以同时应用于整个数据集,也可以重复应用于数据的小块,最终实现与应用于整个数据集相同的结果。你所描述的似乎不属于这一类。
我认为您没有很好地解释您的问题,或者您可能误解了MapReduce。
所谓递归,如果你想把递归函数放在Map或Reducey函数中,答案是肯定的。在这两个阶段都可以使用递归函数。但是,如果你想定义一个递归MapReduce作业,并且你想在Hadoop中这样做,那么在Hadoop定义递归函数是不可能的,或者至少是不安全和直接的
第二个和第三个问题的答案是一样的:第一种情况下可能,如果你指的是递归作业,则不可能。