Im Moment habe ich einen Hadoop-Job, der Zähler mit einem ziemlich großen Namen erstellt.
Zum Beispiel die folgende : stats.counters.server-name.job.job-name.mapper.site.site-name.qualifier.qualifier-name.super-long-string-which-is-not-within-standard-limits
. Dieser Zähler wird auf der Weboberfläche und beim getName()
Methodenaufruf abgeschnitten . Ich habe herausgefunden, dass Hadoop Einschränkungen für den Zählermaximalnamen hat und diese Einstellungs-ID mapreduce.job.counters.counter.name.max
dient zum Konfigurieren dieser Grenze. Also habe ich dies erhöht 500
und das Webinterface zeigt jetzt den vollständigen Zählernamen an. Aber getName()
der Zähler gibt immer noch einen abgeschnittenen Namen zurück.
Könnte jemand dies bitte erklären oder mich auf meine Fehler hinweisen? Vielen Dank.
BEARBEITEN 1
Meine Hadoop-Serverkonfiguration besteht aus einem einzelnen Server mit HDFS, YARN und Map-Reduction. Während der Kartenreduzierung gibt es einige Zählerinkremente und nach Abschluss des Jobs werden ToolRunner
Zähler mit der Verwendung von abgerufen org.apache.hadoop.mapreduce.Job#getCounters
.
BEARBEITEN 2
Die Hadoop-Version ist die folgende:
Hadoop 2.6.0-cdh5.8.0
Subversion http://github.com/cloudera/hadoop -r 042da8b868a212c843bcbf3594519dd26e816e79
Compiled by jenkins on 2016-07-12T22:55Z
Compiled with protoc 2.5.0
From source with checksum 2b6c319ecc19f118d6e1c823175717b5
This command was run using /usr/lib/hadoop/hadoop-common-2.6.0-cdh5.8.0.jar
Ich habe einige zusätzliche Untersuchungen durchgeführt und es scheint, dass dieses Problem eine ähnliche Situation wie ich beschreibt. Aber es ist ziemlich verwirrend, weil ich die Anzahl der Zähler erhöhen kann, aber nicht die Länge des Zählernamens ...
BEARBEITEN 3
Heute habe ich ziemlich viel Zeit damit verbracht, Interna des Hadoop zu debuggen. Einige interessante Sachen:
org.apache.hadoop.mapred.ClientServiceDelegate#getJobCounters
Die Methode gibt eine Reihe von Zählern aus Garn mit TRUNCATED- Namen und FULL- Anzeigenamen zurück.- Konnte Maps und Reduzierer selbst nicht debuggen, aber mit Hilfe der Protokollierung scheint die
org.apache.hadoop.mapreduce.Counter#getName
Methode während der Ausführung des Reduzierers korrekt zu funktionieren.
getName()
Anruf angeben, bei dem der abgeschnittene Name noch zurückgegeben wird? Durchläuft dies die Zähler, die vom übergebendenJob#getCounters()
Client zurückgegeben wurden, nachdem auf den Abschluss des Jobs gewartet wurde, oder handelt es sich um eine separate Anwendung, die Zähler vom Jobverlaufsserver abfragt, oder handelt es sich um etwas ganz anderes? Ich würde erwarten, dass Ihre Konfiguration ausreichend ist. Die Web-Benutzeroberfläche verwendet denselbengetName()
Aufruf. (Es würde jedoch nicht rückwirkend abgeschnittene Zählernamen von Jobs korrigieren, die vor der Konfigurationsänderung gesendet wurden.)stats.counters.server-name.job.job-name.mapper.site.site-name.qualifier.qualifier-name.super-long-string-which-is-not-within-standard-limits
Antworten:
Der Hadoop-Code enthält nichts, was die Zählernamen nach der Initialisierung abschneidet. Wie Sie bereits betont haben,
mapreduce.job.counters.counter.name.max
steuert der Name des Zählers die maximale Länge (mit 64 Symbolen als Standardwert ).Dieses Limit wird bei Anrufen an angewendet
AbstractCounterGroup.addCounter/findCounter
. Der jeweilige Quellcode lautet wie folgt :@Override public synchronized T addCounter(String counterName, String displayName, long value) { String saveName = Limits.filterCounterName(counterName); ...
und eigentlich :
public static String filterName(String name, int maxLen) { return name.length() > maxLen ? name.substring(0, maxLen - 1) : name; } public static String filterCounterName(String name) { return filterName(name, getCounterNameMax()); }
Wie Sie sehen können, wird der Name des Zählers in Bezug auf abgeschnitten gespeichert
mapreduce.job.counters.max
. Im Hadoop-Code gibt es nur eine einzige Stelle, an der der Aufruf von ausgeführtLimits.init(Configuration conf)
wird (von derLocalContainerLauncher
Klasse aufgerufen ):class YarnChild { private static final Logger LOG = LoggerFactory.getLogger(YarnChild.class); static volatile TaskAttemptID taskid = null; public static void main(String[] args) throws Throwable { Thread.setDefaultUncaughtExceptionHandler(new YarnUncaughtExceptionHandler()); LOG.debug("Child starting"); final JobConf job = new JobConf(MRJobConfig.JOB_CONF_FILE); // Initing with our JobConf allows us to avoid loading confs twice Limits.init(job);
Ich glaube, Sie müssen die folgenden Schritte ausführen, um das von Ihnen beobachtete Problem mit den Zählernamen zu beheben:
mapreduce.job.counters.counter.name.max
Konfigurationswert anSie werden immer noch abgeschnittene Zählernamen für alte Jobs sehen, denke ich.
quelle
getName()
scheint veraltet zu seinAlternativ kann
getUri()
eine standardmäßige maximale Länge von 255 verwendet werden.Habe es nicht persönlich ausprobiert, aber es scheint eine mögliche Lösung für dieses Problem zu sein.
quelle
org.apache.hadoop.fs.FileSystem#getName
aber dieses Thema handelt vonorg.apache.hadoop.mapreduce.Counter#getName
und es ist Verhalten.