如何优化这个MapReduce函数,Python, mrjob



我是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()

有两种方法。

1。改进你的流程

你正在做一个分布式字数统计。这个运算是代数的但是你没有利用这个性质。

对于你输入的每个单词,你发送一个记录到reducer。这些字节必须进行分区,通过网络发送,然后由reducer排序。它的效率和可扩展性都不高,映射器发送给reducer的数据量通常是一个瓶颈。

您应该在作业中添加一个组合器。它和电流减速器的作用是一样的。在同一个地址空间中,组合器就在映射器之后运行。这意味着您通过网络发送的数据量不再与您输入的单词数量呈线性关系,而是受到唯一单词数量的限制。通常要低几个数量级。

由于分布式单词计数示例被过度使用,您可以通过搜索"分布式单词计数组合器"轻松找到更多信息。所有代数运算都必须有一个组合子。

2。使用更高效的工具

Mrjob是一个快速编写map reduce作业的好工具。通常,编写python作业比编写Java作业要快。但是它有运行时成本:

    Python通常比Java慢
  1. MRJob比大多数python框架慢,因为它还没有使用typedbytes

您必须决定是否值得使用常规API在Java中重写一些作业。如果您正在编写寿命较长的批处理作业,那么投入一些开发时间来降低运行时成本是有意义的。

从长远来看,编写Java作业通常不会比用python编写作业长得多。但是你必须做一些前期投资:创建一个带有构建系统的项目,打包它,部署它等等。使用MRJob,您只需要执行您的python文本文件。

Cloudera在几个月前做了一个Hadoop python框架的基准测试。MRJob比他们的Java作业慢得多(5到7倍)。当typedbytes可用时,MRJob的性能应该会提高,但Java作业仍然会快2到3倍。

相关内容

  • 没有找到相关文章

最新更新