Vor*_*Vor 1 python hadoop mapreduce 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()
Run Code Online (Sandbox Code Playgroud)
有两种方法可以遵循。
1. 改进您的流程
您正在进行分布式字数统计。此操作是代数运算,但您没有利用此属性。
对于您输入的每个单词,您都会向减速器发送一条记录。这些字节必须被分区,通过网络发送,然后由减速器排序。它既不高效也不可扩展,映射器发送到减速器的数据量通常是一个瓶颈。
你应该在你的工作中添加一个组合器。它将与您当前的减速器做完全相同的事情。组合器在同一地址空间中的映射器之后运行。这意味着您通过网络发送的数据量不再与输入的字数成线性关系,而是受唯一字数的限制。这通常低几个数量级。
由于分布式单词计数示例被过度使用,您可以通过搜索“分布式单词计数组合器”轻松找到更多信息。所有代数运算都必须有一个组合器。
2. 使用更高效的工具
Mrjob 是快速编写 map reduce 作业的好工具。通常,编写 Python 作业比编写 Java 作业更快。但是它有运行时成本:
typedbytes您必须决定是否值得使用常规 API 用 Java 重写一些作业。如果您正在编写长期存在的批处理作业,那么投入一些开发时间来降低运行时成本可能是有意义的。
从长远来看,编写 Java 作业通常不会比用 Python 编写的时间长。但是您必须进行一些前期投资:使用构建系统创建一个项目、打包、部署它等等。使用 MRJob,您只需要执行您的 Python 文本文件。
Cloudera几个月前对 Hadoop python 框架进行了基准测试。MRJob 比他们的 Java 工作慢得多(5 到 7 倍)。当 typedbytes 可用时,MRJob 性能应该会提高,但 Java 作业仍然会快 2 到 3 倍。
| 归档时间: |
|
| 查看次数: |
3003 次 |
| 最近记录: |