我是Map / Reduce原理和python mrjob框架的新手,我编写了这个示例代码,它工作正常,但我想知道我可以改变它以使其“完美”/更高效
from mrjob.job import MRJob
import operator
import re
# append result from each reducer
output_words = []
class MRSudo(MRJob):
def init_mapper(self):
# move list of tuples across mapper
self.words = []
def mapper(self, _, line):
command = line.split()[-1]
self.words.append((command, 1))
def final_mapper(self):
for word_pair in self.words:
yield word_pair
def reducer(self, command, count):
# append tuples to the list
output_words.append((command, sum(count)))
def final_reducer(self):
# Sort tuples in the list by occurence
map(operator.itemgetter(1), output_words)
sorted_words = sorted(output_words, key=operator.itemgetter(1), reverse=True)
for result in sorted_words:
yield result
def steps(self):
return [self.mr(mapper_init=self.init_mapper,
mapper=self.mapper,
mapper_final=self.final_mapper,
reducer=self.reducer,
reducer_final=self.final_reducer)]
if __name__ == '__main__':
MRSudo.run()
答案 0 :(得分:4)
有两种方法可以遵循。
<强> 1。改善您的流程
您正在进行分布式字数统计。此操作是代数的,但您没有利用此属性。
对于输入的每个单词,您都要向减速器发送记录。必须对这些字节进行分区,通过网络发送,然后由reducer进行排序。它既不高效也不可扩展,映射器向减速器发送的数据量通常是一个瓶颈。
您应该为工作添加一个组合器。它将与您当前的减速器完全相同。组合器在映射器之后运行在同一地址空间中。这意味着您通过网络发送的数据量不再与输入的字数呈线性关系,而是受唯一字数量的限制。这通常要低几个数量级。
由于分布式字数统计示例被过度使用,您可以通过搜索“分布式字数统计器”轻松找到更多信息。所有代数运算都必须有一个组合器。
<强> 2。使用更有效的工具
Mrjob是快速编写地图减少工作的好工具。通常,编写python Job比使用Java更快。但是它有运行时成本:
typedbytes
您必须决定是否值得使用常规API重写Java中的一些作业。如果您正在编写长期批处理作业,那么投入一些开发时间来降低运行时成本是有意义的。
从长远来看,编写Java Job通常不会比在python中编写它更长。但是你必须做一些前期投资:用构建系统创建一个项目,打包它,部署它等。使用MRJob你只需要执行你的python文本文件。
几个月前Cloudera做了benchmark of the Hadoop python frameworks。 MRJob比他们的Java工作慢5到7倍。当typedbytes可用时,MRJob的表现应该会提高,但Java工作的速度仍然会快2至3倍。