Hadoop截断/不一致的计数器名称

时间:2017-01-17 15:32:33

标签: java hadoop mapreduce yarn

现在,我有一个Hadoop工作,它创建了一个非常有名的计数器。

例如,以下一个:stats.counters.server-name.job.job-name.mapper.site.site-name.qualifier.qualifier-name.super-long-string-which-is-not-within-standard-limits。此计数器在Web界面和getName()方法调用上被截断。我发现Hadoop对计数器最大名称有限制,此设置标识mapreduce.job.counters.counter.name.max用于配置此限制。所以我将其增加到500,web界面现在显示完整的计数器名称。但是计数器的getName()仍然返回截断的名称。

有人可以解释一下,还是指出我的错误?谢谢。

编辑1

我的Hadoop服务器配置包含单个服务器,其中包含HDFS,YARN和map-reduce。在map-reduce期间,有一些计数器增量,在作业完成后,在ToolRunner中,我使用org.apache.hadoop.mapreduce.Job#getCounters获取计数器。

编辑2

Hadoop版本如下:

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

我做了一些额外的调查,this issue似乎描述了与我类似的情况。但这很令人困惑,因为我可以增加计数器的数量而不是计数器名称的长度......

编辑3

今天,我花了很多时间调试Hadoop的内部。一些有趣的东西:

  1. org.apache.hadoop.mapred.ClientServiceDelegate#getJobCounters方法使用 TRUNCATED 名称和 FULL 显示名称从yarn返回一组计数器。
  2. 无法自行调试map和reducers,但在日志记录的帮助下,似乎org.apache.hadoop.mapreduce.Counter#getName方法在reducer执行期间正常工作。

2 个答案:

答案 0 :(得分:2)

Hadoop代码中没有任何东西会在初始化后截断计数器名称。 因此,正如您已经指出的那样,mapreduce.job.counters.counter.name.max控制着计数器名称的最大长度(default value中有64个符号)。

在调用AbstractCounterGroup.addCounter/findCounter期间会应用此限制。 各自的源代码是following

@Override
public synchronized T addCounter(String counterName, String displayName,
                                 long value) {
  String saveName = Limits.filterCounterName(counterName);
  ...

actually

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());
}

如您所见,计数器的名称相对于mapreduce.job.counters.max被截断了。 依次,只有一个single place in Hadoop code会执行对Limits.init(Configuration conf)的调用(从LocalContainerLauncher类调用):

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);

我相信您需要执行以下步骤来解决您观察到的计数器名称问题:

  1. 调整mapreduce.job.counters.counter.name.max配置值
  2. 重新启动YARN / MapReduce服务
  3. 重新执行工作

您仍然会看到我认为旧工作的计数器名称被删掉。

答案 1 :(得分:1)

getName()似乎已被弃用

或者,可以使用默认最大长度为255的getUri()

  

文档链接:getUri()

尚未亲自尝试过,但这似乎可以解决此问题。