1

Hadoop の map-reduce ジョブをデバッグするのは面倒です。stdout に出力できますが、これらのログは、MR ジョブが実行されたさまざまなマシンすべてに表示されます。jobtracker に移動して自分の仕事を見つけ、個々のマッパーをクリックしてタスク ログにアクセスできますが、20 以上のマッパー/リデューサーがある場合、これは非常に面倒です。

各マッパー/リデューサーがどのマシンで実行されているかを把握するためにジョブ トラッカーをスケープし、ログを 1 つの中央の場所に scp で戻して、それらをまとめて分類できるスクリプトを作成する必要があるのではないかと考えていました。これを行うのに時間を無駄にする前に、ジョブのマッパーとリデューサーの統合された stdout ログを取得するより良い方法を知っている人はいますか?

4

3 に答える 3

1

私はこれを次の方法で行います:

一般的なデバッグ (つまり、ジョブが機能することのテスト) では、ローカル マシンで Hadoop をスタンドアロン モードで実行し、データの小さなサンプルを使用します。このように、hadoop は他の Java アプリと同じように機能し、マッパーまたはリデューサーの stdout をコンソールに表示します。

特定のバグ (つまり、ジョブはローカル マシンでは正常に実行されますが、本番環境では停止します) については、コードを微調整して、デバッグ時に通常 stdout に送信するものをジョブの出力として配置します。そうすれば、ジョブの結果を確認してデバッグの洞察を得ることができます。これはきれいではありませんが、うまく機能します。

もう 1 つのオプションは、ジョブトラッカーでノードのログを確認することです。それらにはすべての stdout と stderr があります。ただし、いくつかの理由により、これは上記の解決策よりもはるかに複雑であることがわかりました(ログはしばらくすると削除され、いくつかのノードを探す必要があるなど)

于 2013-08-30T04:30:18.937 に答える
1

そのため、これを行うための Python スクリプトを作成するだけになりました。それは恐ろしいことではありませんでした。他の誰かが使用したい場合のスクリプトを次に示します。明らかに、ハードコーディングされた URL などではなく、より多くのエラー チェックが必要ですが、アイデアは得られます。美しいスープをダウンロードする必要があることに注意してください

#!/usr/bin/python
import sys
from bs4 import BeautifulSoup as BS
from urllib2 import urlopen
import re

TRACKER_BASE_URL = 'http://my.tracker.com:50030/'
trackerURLformat = TRACKER_BASE_URL + 'jobtasks.jsp?jobid=%s&type=%s&pagenum=1' # use map or reduce for the type

def findLogs(url):
    finalLog = ""

    print "Looking for Job: " + url
    html = urlopen(url).read()
    trackerSoup = BS(html)
    taskURLs = [h.get('href') for h in trackerSoup.find_all(href=re.compile('taskdetails'))]

    # Now that we know where all the tasks are, go find their logs
    logURLs = []
    for taskURL in taskURLs:
        taskHTML = urlopen(TRACKER_BASE_URL + taskURL).read()
        taskSoup = BS(taskHTML)
        allLogURL = taskSoup.find(href=re.compile('all=true')).get('href')
        logURLs.append(allLogURL)

    # Now fetch the stdout log from each
    for logURL in logURLs:
        logHTML = urlopen(logURL).read()
        logSoup = BS(logHTML)
        stdoutText = logSoup.body.pre.text.lstrip()
        finalLog += stdoutText

    return finalLog


def main(argv):
    with open(argv[1] + "-map-stdout.log", "w") as f:
        f.write(findLogs(trackerURLformat % (argv[1], "map")))
        print "Wrote mapers stdouts to " + f.name

    with open(argv[1] + "-reduce-stdout.log", "w") as f:
        f.write(findLogs(trackerURLformat % (argv[1], "reduce")))
        print "Wrote reducer stdouts to " + f.name

if __name__ == "__main__":
    main(sys.argv)
于 2013-08-30T13:08:37.913 に答える
0

私の経験では、ログで調べたい問題の原因となった map/reduce の試行が正確にわかっている場合は、20 以上の map/reduce 出力リンクをクリックする必要はありません。そのため、疑いを引き起こすためにそこにある例外をスローするか、カウンターをインクリメントするときに、常に Context.setStatus("Warn message here") を使用します。

setStatus の詳細: http://hadoop.apache.org/docs/r1.1.1/api/org/apache/hadoop/mapreduce/TaskInputOutputContext.html#setStatus(java.lang.String)

https://www.inkling.com/read/hadoop-definitive-guide-tom-white-3rd/chapter-5/running-on-a-cluster (セクション ジョブのデバッグ)

于 2014-07-14T22:40:11.333 に答える