2013-08-29 5 views
1

Déboguer les travaux Hadoop map-reduce est une source de problèmes. Je peux imprimer sur stdout, mais ces journaux s'affichent sur toutes les machines sur lesquelles le travail MR a été exécuté. Je peux aller dans le jobtracker, trouver mon travail, et cliquer sur chaque mappeur pour accéder à son journal des tâches, mais c'est extrêmement compliqué quand vous avez plus de 20 mappeurs/réducteurs. Je pensais que je pourrais avoir à écrire un script qui parcourrait le traqueur de travail pour comprendre quelle machine chacun des mappeurs/réducteurs a fonctionné, puis scp les journaux à un emplacement central où ils pourraient être chat Ed ensemble. Avant de perdre mon temps à le faire, quelqu'un connaît-il une meilleure façon d'obtenir un seul journal consolidé pour les mappeurs et les réducteurs d'un travail?Consolider les journaux MapReduce

Répondre

1

Donc j'ai fini par créer un script Python pour cela . Ce n'était pas horrible. Voici le script au cas où quelqu'un d'autre veut l'utiliser. Évidemment, il faut plus de vérification des erreurs, pas d'URL codées en dur, etc., mais vous avez l'idée. Note, vous devez télécharger Beautiful Soup

#!/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) 
+1

J'ai fait quelques changements dans ce script (l'URL de base de JobTracker est un param) et fait le travail sur python3. Si vous voulez le voir, c'est ici: https://github.com/OhadR/mapreduce-logs-consolidator – OhadR

1

Je le fais de la manière suivante:

Pour le débogage général (à savoir le test que le travail fonctionne) je lance Hadoop en mode autonome sur ma machine locale avec un petit échantillon des données. De cette façon, hadoop fonctionne comme toute autre application java et affiche la sortie standard des mappeurs ou des réducteurs dans la console. Pour des bogues spécifiques (c'est-à-dire que le travail s'exécute bien sur ma machine locale, mais meurt en production), je modifie simplement le code pour mettre en sortie ce que j'aurais normalement envoyé à stdout lors du débogage. De cette façon, vous pouvez vérifier le résultat du travail pour les informations de débogage. Ce n'est pas joli mais ça marche bien.

Une autre option consiste à vérifier les journaux du nœud dans le jobtracker. Ils ont tous les stdout et stderr. Cependant, pour plusieurs raisons, j'ai trouvé cela très compliqué que la solution décrite ci-dessus (les journaux sont supprimés après un certain temps, plusieurs nœuds à rechercher, etc)

0

Mon expérience est que vous n'avez pas besoin de cliquer 20+ map/reduce liens de sortie lorsque vous savez exactement ce que map/reduce tentative a causé le problème que vous voulez examiner par journaux. C'est pourquoi j'utilise toujours Context.setStatus ("Avertir le message ici") quand je lance une exception ou un compteur d'incrément qui est là pour éveiller les soupçons.

Plus sur 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 (section Mise au point d'un emploi)