hadoop namenode使用损坏的度量路径将fsnamesystem度量发送到graphite

laawzig2  于 2021-05-27  发布在  Hadoop
关注(0)|答案(1)|浏览(415)

我使用以下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等(在这里有详细描述)
我将所有tcp请求都转储到了carbon,我得到的是:

<...>
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应该是disctinct度量,但它以某种方式出现在度量路径中,度量值在等号之后,而且它根本不作为distinct度量发送/接收(因为tcpdump不会将此度量作为distrinct度量捕获数据包)。
graphitesink或hadoop metric 2是否有问题,如何解决?

o2g1uqev

o2g1uqev1#

度量记录由标记(如hostname、context、sessionid等)和度量(如capacitytotal、capacityused等)组成。
将度量记录推入 GraphiteSink 例如,它遍历所有标记,将它们组合成前缀,然后用标记的前缀导出每个度量(在该度量记录中)。
在hadoop2.9.1中 TotalSyncTimes 引入了(string)度量,它反映了在各种编辑日志上同步操作所花费的时间—每个活动日志的时间(例如,“9 2”表示两个活动日志,第一个为9毫秒,另一个为2毫秒)。
看看hdfs的代码(2.9.2+2.7.3),string类型的每个度量值都会自动转换为一个标记:
问题度量的定义:

@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 "";
    }
  }

(请注意,公制注解没有类型,默认情况下类型为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 总之,您可以采取以下几种解决方案:
使用不同的方法(不通过metrics2)
创建一个不同的graphite sink,它更能识别标记(我们所做的)并附加到metrics2,而不是grahpitesink
顺便说一句,我仍然不确定这是hdfs代码中的一个bug,还是设计上应该是这样的。

相关问题