1

我对 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()
4

1 回答 1

5

有两种方法可以遵循。

1. 改进您的流程

您正在进行分布式字数统计。此操作是代数的,但您没有利用此属性。

对于您输入的每个单词,您都会向减速器发送一条记录。这些字节必须被分区,通过网络发送,然后由reducer排序。它既不高效也不可扩展,映射器发送到减速器的数据量通常是一个瓶颈。

你应该在你的工作中添加一个组合器。它的作用与您当前的减速器完全相同。组合器在同一地址空间中的映射器之后运行。这意味着您通过网络发送的数据量不再与输入的字数呈线性关系,而是受唯一字数的限制。这通常要低几个数量级。

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

2. 使用更高效的工具

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

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

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

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

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

于 2013-04-06T08:56:37.890 回答