Hadoop Namenode将FSNamesystem指标发送到带有损坏的指标路径的石墨

时间:2019-02-20 16:58:46

标签: java hadoop metrics graphite graphite-carbon

我使用以下hadoop-metrics2.properties配置:

*.sink.graphite.class=org.apache.hadoop.metrics2.sink.GraphiteSink
*.period=10
namenode.sink.graphite.server_host=alex-monitoring
namenode.sink.graphite.server_port=2015
namenode.sink.graphite.metrics_prefix=prefix

Carbon接收除FSNamesystem度量标准之外的所有度量标准,例如CapacityUsed,CapacityUsed等(完整描述here

我将所有tcp请求都转储到了碳中,这就是我得到的:

<...>
prefix.dfs.FSNamesystem.Context=dfs.HAState=active.TotalSyncTimes=17 .Hostname=alex-hadoop1.TotalSyncCount 2 1550676511
prefix.dfs.FSNamesystem.Context=dfs.HAState=active.TotalSyncTimes=17 .Hostname=alex-hadoop1.NumInMaintenanceLiveDataNodes 0 1550676511
prefix.dfs.FSNamesystem.Context=dfs.HAState=active.TotalSyncTimes=17 .Hostname=alex-hadoop1.NumInMaintenanceDeadDataNodes 0 1550676511
<...>

这里的问题是路径中的空格:TotalSyncTimes=17 .Hostname= TotalSyncTimes应该是一个不同的度量标准,但是它在度量标准路径中以等号后的度量标准值出现,并且也根本不作为不同的度量标准发送/接收(因为tcpdump不会捕获与该度量标准不同的数据包)。

GraphiteSink或Hadoop指标2是否有问题,我该如何解决?

1 个答案:

答案 0 :(得分:0)

指标记录由标签(例如主机名,上下文,会话ID等)和指标(例如CapacityTotal,CapacityUsed等)组成。

将度量标准记录推入GraphiteSink实例时,它将遍历其所有标记,将它们组合为前缀,然后导出带有该标记前缀的每个度量标准(在该度量标准记录内)。

在Hadoop 2.9.1中,引入了TotalSyncTimes(字符串)度量标准,该度量标准反映了在各种编辑日志上进行同步操作所花费的时间-每个活动日志的时间(例如,“ 9 2”表示两个活动日志,前9毫秒,其他2毫秒。

查看HDFS的代码(2.9.2 + 2.7.3),看起来每个字符串类型的指标都会自动转换为标签:

有问题的指标的定义:

@Metric({"TotalSyncTimes",
              "Total time spend in sync operation on various edit logs"})
  public String getTotalSyncTimes() {
    JournalSet journalSet = fsImage.editLog.getJournalSet();
    if (journalSet != null) {
      return journalSet.getSyncTimes();
    } else {
      return "";
    }
  }

(请注意,Metric注释没有类型,默认情况下为DEFAULT类型)

然后,当它被迭代时,它将被转换为带有标签的字符串:

private MutableMetric newImpl(Type metricType) {
        Class<?> resType = this.method.getReturnType();
        switch(metricType) {
        case COUNTER:
            return this.newCounter(resType);
        case GAUGE:
            return this.newGauge(resType);
        case DEFAULT:
            return resType == String.class ? this.newTag(resType) : this.newGauge(resType);
        case TAG:
            return this.newTag(resType);
        default:
            Contracts.checkArg(metricType, false, "unsupported metric type");
            return null;
        }
    }

这意味着TotalSyncTimes将嵌套在标签中:

...
name: "Hadoop:service=NameNode,name=FSNamesystem",
modelerType: "FSNamesystem",
tag.Context: "dfs",
tag.HAState: "active",
tag.TotalSyncTimes: "9 2 ",
...

因此,当具有TotalSyncTimes的度量标准记录被推到GraphiteSink时,它将为每个度量标准附加一个无效前缀(带空格),就像您显示的那样:

HAState=active.TotalSyncTimes=17 .Hostname=alex-hadoop

最重要的是,您可以采取几种解决方案:

  1. 使用其他方法(不是通过metrics2)
  2. 创建另一个石墨槽,该石墨槽更易于识别标签(我们所做的工作),并将其附加到metrics2而不是GrahpiteSink

顺便说一句,我仍然不确定这是HDFS代码中的错误还是应该是设计使然。