2013-04-05 13 views
1

我很新的Map/Reduce原理和python mrjob框架,我寫了這個示例代碼,它工作正常,但我想知道我可以改變什麼它使它「完美」/更高效。如何優化這個MapReduce函數,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

這聽起來更像是http://codereview.stackexchange.com的問題。 – 2013-04-05 20:34:52

+0

感謝您指出了這一點,但我正在詢問如何提高此代碼的性能。 – Vor 2013-04-05 20:35:54

+0

是的,這正是[codereview是有](http://codereview.stackexchange.com/faq)。 – 2013-04-05 20:36:52

回答

4

有兩種方法可以關注。

1.提高你的過程

你正在做分佈式字數。這個操作是代數的,但是你沒有利用這個屬性。

對於您輸入的每一個單詞,您都將記錄發送給減速器。這些字節必須進行分區,通過網絡發送,然後由減速器進行排序。它既不高效也不可擴展,映射器發送給還原器的數據量通常是瓶頸。

您應該爲您的工作添加組合器。它將完成與您當前的減速器完全相同的操作。組合器在映射器之後的相同地址空間中運行。這意味着您通過網絡發送的數據量不再與輸入的字數成線性關係,而是受到唯一字數的限制。通常要低幾個數量級。

由於分佈式字數統計過度使用,您可以通過搜索「分佈式字數組合器」輕鬆找到更多信息。所有的代數運算都必須有一個組合器。

2.使用更有效的工具

Mrjob是快速寫map reduce作業一大利器。通常,編寫python Job比Java更快。但是它具有運行成本:

  1. Python是通常比Java慢
  2. MRJob比大多數蟒框架的慢,因爲是沒有的,但使用typedbytes

你必須決定如果它使用常規API值得用Java重寫一些你的工作。如果您正在編寫長期批量作業,那麼投入一些開發時間來降低運行時成本可能是有意義的。

從長遠來看,編寫Java作業通常不會比在Python中編寫它要長很多。但是你必須做一些前期投資:用一個構建系統創建一個項目,打包它,部署它等。使用MRJob,你只需要執行你的python文本文件。

Cloudera幾個月前做了benchmark of the Hadoop python frameworks。 MRJob比他們的Java工作要慢得多(5到7次)。當類型字節可用時,MRJob性能應該會提高,但Java作業速度仍然會提高2到3倍。