我写了一个MapReduce作业,它对数据集进行了ngram计数。结果是一百个300MB格式的文件,<ngram>\t<count>
。我想将这些结合到一个结果中,但我的几次尝试组合已经崩溃(“任务跟踪器已经消失”)。我的暂停时间是8小时,这次崩溃发生在8.5小时左右,所以可能有关系。我有#reducers = 5(与节点数相同)。也许我只需要留出更多时间,虽然错误似乎并没有表明这一点。我怀疑我的节点过载,并且没有响应。我的理论是我的减速器可以使用一些优化。
我正在使用cat
作为我的mapper,以及我的reducer的以下python脚本:
#!/usr/bin/env python
import sys
counts = {}
for line in sys.stdin:
line = line.strip()
key, count = line.split('\t', 1)
try:
count = int(count)
except ValueError:
continue
if key not in counts:
counts[key] = 0
counts[key] += count
for key in sorted(counts.keys()):
print '%s\t%s'% (key, counts[key])
更新
正如我在其中一条评论中暗示的那样,我对Hadoop自动进行排序感到困惑。在Web UI中,reducer状态显示了几个不同的阶段,包括“sort”和“reduce”。由此我假设Hadoop在将mapper输出发送到reduce之前对其进行排序,但是不清楚的是,如果排序是在发送到reducer的所有数据上,还是在每个文件减少之前。换句话说,我的映射器需要100个fiels,将其分成400个输出,每个输出只需cat
- 它们到减速器,然后减速器(总共5个)每个接收这80个流。排序是否结合所有80,或者排序1,减少它;等等?基于可能明显不表示实际行为的图表,排序过程在任何减少之前发生。如果排序对所有输入文件进行排序,那么我可以简化我的reducer以不存储所有计数的字典,并且只需在密钥更改后打印出key-totalCount对。
关于组合器的使用,我不认为这对我的情况有利,因为我正在减少的数据已经减少了我想要组合的100个文件。由于我的#nodes = #recelers(5&amp; 5),因此还没有任何东西可以合并,而减速器还没有。
答案 0 :(得分:2)
问题在于我对MapReduce如何工作的误解。进入Reducer的所有数据都已排序。我上面的代码完全没有优化。相反,我只是跟踪当前键,然后在出现新键时打印出前一个当前键。
#!/usr/bin/env python
import sys
cur_key = None
cur_key_count = 0
for line in sys.stdin:
line = line.strip()
key, count = line.split('\t', 1)
try:
count = int(count)
except ValueError:
continue
# if new key, reset count, note current key, and output lastk key's result
if key != cur_key:
if cur_key is not None:
print '%s\t%s'% (cur_key, cur_key_count)
cur_key = key
cur_key_count = 0
cur_key_count += count
# printing out final key if set
if cur_key:
print '%s\t%s'% (cur_key, cur_key_count)
答案 1 :(得分:1)
使用top
检查您的reducer是否受CPU限制,并且在运行时不受IO限制(可能导致交换)。
每个主机8小时/ 20个工作是每300Mb工作24分钟
您可以使用heapq
,以便内存中构建的数据结构保持排序:
见下文第8.4.1节:
http://docs.python.org/library/heapq.html