Python MRJob lib を使用して mapreduce ジョブを実行しようとしていますが、Hadoop クラスター全体に適切に分散するのに問題があります。mapreduce の基本原則が欠けているだけだと思います。私のクラスターは小さな、1 つのマスターと 1 つのスレーブのテスト クラスターです。基本的な考え方は、パラメーターを含む一連の Web ページを要求し、それらを分析して、Web ページのいくつかのプロパティを返すというものです。
私のマップ関数への入力は、次のようなパラメーターを持つ URL のリストです。
http://guelph.backpage.com/automotive/?layout=bla&keyword=towing
http://guelph.backpage.com/whatever/?p=blah
http://semanticreference.com/search.html?go=Search&q=red
http://copiahcounty.wlbt.com/h/events?ename=drupaleventsxmlapi&s=rrr
http://sweetrococo.livejournal.com/34076.html?mode=ffff
初期入力のキーと値のペアは、key:None、val:URL のみです。
以下は私のマップ機能です:
def mapper(self, key, url):
'''Yield domain as the key, and (url, query parameter) tuple as the value'''
parsed_url = urlparse(url)
domain = parsed_url.scheme + "://" + parsed_url.netloc + "/"
if self.myclass.check_if_param(parsed_url):
parsed_url_query = parsed_url.query
url_q_dic = parse_qs(parsed_url_query)
for query_param, query_val in url_q_dic.iteritems():
#yielding a tuple in mrjob will yield a list
yield domain, (url, query_param)
非常に単純です。URL にパラメーターが含まれていることを確認し、URL のドメインをキーとして生成し、URL とクエリ パラメーターを値として提供するタプルを生成するだけです。は次のとおりです。
def reducer(self, domain, url_query_params):
final_list = []
for url_query_param in url_query_params:
url_to_list_props = url_query_param[0]
param_to_list_props = url_query_param[1]
#set our target that we will request and do some analysis on
self.myclass.set_target(url_to_list_props, param_to_list_props)
#perform a bunch of requests and do analysis on the URL requested
props_list = self.myclass.get_props()
for prop in props_list:
final_list.append(prop)
#index this stuff to a central db
MapReduceIndexer(domain, final_list).add_prop_info()
yield domain, final_list
私の問題は、レデューサー タスクが 1 つしか実行されないことです。レデューサー タスクの数は、マッパーによって発行された一意のキーの数と等しいと予想されます。上記のコードの最終結果は、マスターで実行されるレデューサーが 1 つあるということですが、スレーブは何もせずに何もせず、明らかに理想的ではありません。私の出力では、いくつかのマッパー タスクが開始されていることに気付きましたが、常に 1 つのリデューサー タスクのみです。それ以外は、タスクはスムーズに実行され、すべてが期待どおりに機能します。
私の質問は...一体私は何を間違っているのですか? reduce ステップを誤解しているか、キーと値のペアをどこかで台無しにしていますか? このジョブで複数のレデューサーが実行されていないのはなぜですか?
更新:OKなので、回答から mapred.reduce.tasks をより高く増やしました(これはデフォルトであり、現在は1であることに気づきました)。これが確かに、1つのレデューサーを取得していた理由です。3 つの削減タスクが同時に実行されていることがわかります。解決する必要があるスレーブでインポートエラーが発生しましたが、少なくともどこかに到達しています...