TT Bigdata TT Bigdata
首页
  • 部署专题

    • 常规安装
    • 一键部署
  • 组件专题

    • 安装教程
    • 魔改分享
  • 版本专题

    • 更新说明
    • BUG临时处理
  • Ambari-Env

    • 环境准备
    • 开始使用
  • 组件编译

    • 专区—Ambari
    • 专区—Bigtop-官方组件
    • 专区—Bigtop-扩展组件
  • 报错解决

    • 专区—Ambari
    • 专区—Bigtop
  • 其他技巧

    • APT仓库增量更新
    • Maven镜像加速
    • Gradle镜像加速
    • Bower镜像加速
    • 虚拟环境思路
    • R环境安装+一键安装脚本
    • Ivy配置私有镜像仓库
    • Node.js 多版本共存方案
    • Ambari Web本地启动
    • Npm镜像加速
    • PostgreSQL快速安装
    • Temurin JDK 23快速安装
  • 成神之路

    • 专区—Ambari
    • 专区—Ambari-Metrics
    • 专区—Bigtop
  • 集成案例

    • Redis集成教学
    • Dolphin集成教学
    • Doris集成教学
    • 持续整理...
  • 核心代码

    • 各组件代码
    • 通用代码模板
  • 国产化&其他系统

    • Rocky系列
    • Ubuntu系列
  • Grafana监控方案

    • Ambari-Metrics插件
    • Infinity插件
  • 支持&共建

    • 蓝图愿景
    • 合作共建
登陆
GitHub (opens new window)

JaneTTR

数据酿造智慧,每一滴都是沉淀!
首页
  • 部署专题

    • 常规安装
    • 一键部署
  • 组件专题

    • 安装教程
    • 魔改分享
  • 版本专题

    • 更新说明
    • BUG临时处理
  • Ambari-Env

    • 环境准备
    • 开始使用
  • 组件编译

    • 专区—Ambari
    • 专区—Bigtop-官方组件
    • 专区—Bigtop-扩展组件
  • 报错解决

    • 专区—Ambari
    • 专区—Bigtop
  • 其他技巧

    • APT仓库增量更新
    • Maven镜像加速
    • Gradle镜像加速
    • Bower镜像加速
    • 虚拟环境思路
    • R环境安装+一键安装脚本
    • Ivy配置私有镜像仓库
    • Node.js 多版本共存方案
    • Ambari Web本地启动
    • Npm镜像加速
    • PostgreSQL快速安装
    • Temurin JDK 23快速安装
  • 成神之路

    • 专区—Ambari
    • 专区—Ambari-Metrics
    • 专区—Bigtop
  • 集成案例

    • Redis集成教学
    • Dolphin集成教学
    • Doris集成教学
    • 持续整理...
  • 核心代码

    • 各组件代码
    • 通用代码模板
  • 国产化&其他系统

    • Rocky系列
    • Ubuntu系列
  • Grafana监控方案

    • Ambari-Metrics插件
    • Infinity插件
  • 支持&共建

    • 蓝图愿景
    • 合作共建
登陆
GitHub (opens new window)
  • 试读&介绍

  • Ambari-Metrics解读【简写AMS】

    • 源码下载及环境初始化
    • 项目目录及模块解读
    • AMS-Collector剖析

    • AMS-Collector表结构实战

    • AMS-Collector-元数据-接口实战

    • AMS-Collector-指标查询-接口实战

      • [/metrics] — 监控数据接口查询方法
      • [/metrics] — 请求参数概括及详解索引
      • [/metrics] — Service 代码整体逻辑概览
      • [/metrics] — metricNames 生命周期
      • [/metrics] — seriesAggregateFunc生命周期
      • [/metrics] — getUuidsForGetMetricQuery精讲
      • [/metrics] — applyTopNCondition精讲
      • [/metrics] — getAggregateMetricRecords精讲
      • [/metrics] — getMetricRecords精讲
        • 一、方法入口与执行框架
        • 二、getLatestMetricRecords:点查询逻辑
        • 三、prepareGetMetricsSqlStmt:SQL 拼装逻辑
        • 四、appendMetricFromResultSet:结果拼装
        • 五、getTimelineMetricsFromResultSet:秒表特殊逻辑
        • 六、秒表 vs 聚合表差异
        • 七、调用链路梳理
      • [/metrics] — 临时指标精讲
    • AMS-Collector-普通指标写入-接口实战

    • AMS-Collector-聚合指标写入-接口实战

  • GOD-Ambari-Metrics
  • Ambari-Metrics解读【简写AMS】
  • AMS-Collector-指标查询-接口实战
JaneTTR
2025-09-15
目录

[/metrics] — getMetricRecords精讲

# 一、方法入口与执行框架

源码如下:

public TimelineMetrics getMetricRecords(
  final Condition condition, Multimap<String, List<Function>> metricFunctions)
  throws SQLException, IOException {

  validateConditionIsNotEmpty(condition);

  Connection conn = getConnection();
  PreparedStatement stmt = null;
  ResultSet rs = null;
  TimelineMetrics metrics = new TimelineMetrics();

  try {
    // get latest
    if (condition.isPointInTime()){
      getLatestMetricRecords(condition, conn, metrics);
    } else {
      if (condition.getEndTime() >= condition.getStartTime()) {

        if (CollectionUtils.isNotEmpty(condition.getUuids())) {
          stmt = PhoenixTransactSQL.prepareGetMetricsSqlStmt(conn, condition);
          rs = stmt.executeQuery();
          while (rs.next()) {
            appendMetricFromResultSet(metrics, condition, metricFunctions, rs);
          }
        }

        if (CollectionUtils.isNotEmpty(condition.getTransientMetricNames())) {
          stmt = PhoenixTransactSQL.prepareTransientMetricsSqlStmt(conn, condition);
          if (stmt != null) {
            rs = stmt.executeQuery();
            while (rs.next()) {
              TransientMetricReadHelper.appendMetricFromResultSet(metrics, condition, metricFunctions, rs);
            }
          }
        }
      } else {
        LOG.warn("Skipping metrics query because endTime < startTime");
      }
    }

  } catch (PhoenixIOException pioe) {
    // 针对 hash join cache 过期的 fallback
  } catch (RuntimeException ex) {
    // 针对 TimeRange 异常的兜底
  } finally {
    closeQuietly(rs, stmt, conn);
  }

  LOG.debug("Metrics records size: " + metrics.getMetrics().size());
  return metrics;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

执行分支:

  • condition.isPointInTime() → 走 getLatestMetricRecords(但实际不会触发,因为时间必须带上)

  • 否则进入常规 SQL 路径:

    • UUID 非空 → prepareGetMetricsSqlStmt
    • transient 指标 → prepareTransientMetricsSqlStmt

# 二、getLatestMetricRecords:点查询逻辑

尽管不会在 REST 请求中触发,这里依然保留逻辑,方便内部调用。

image-20250916141313182

对应 SQL:

SELECT E.UUID, E.SERVER_TIME, E.METRIC_SUM, E.METRIC_MAX, E.METRIC_MIN,
       E.METRIC_COUNT, E.METRICS
FROM METRIC_RECORD_UUID E
INNER JOIN (
   SELECT UUID, MAX(SERVER_TIME) AS MAX_SERVER_TIME
   FROM METRIC_RECORD_UUID
   GROUP BY UUID
) I
ON E.UUID = I.UUID
AND E.SERVER_TIME = I.MAX_SERVER_TIME;
1
2
3
4
5
6
7
8
9
10

它的作用是:为每个 UUID 取出 最新一条监控数据。 由于 UUID 是二进制字段,在外部 SQL 工具里很难直接传参:

image-20250916142234106

返回值示例:

{
  "1758003546583": 0.0,
  "1758003556582": 1.0,
  "1758003566583": 1.0,
  "1758003576582": 1.0
}
1
2
3
4
5
6

# 三、prepareGetMetricsSqlStmt:SQL 拼装逻辑

常规查询走 PhoenixTransactSQL.prepareGetMetricsSqlStmt。

image-20250916144021402

这里根据请求中的精度(precision)决定查询表:

精度 表名 特殊字段
秒级 METRIC_RECORD_UUID METRICS JSON
分级 METRIC_RECORD_MINUTE_UUID 聚合值列
时级 METRIC_RECORD_HOURLY_UUID 聚合值列
天级 METRIC_RECORD_DAILY_UUID 聚合值列

差异点

秒表多了一个 METRICS JSON 字段,用于保存原始时序。 分钟、小时、天表只保存聚合值(SUM、AVG、MAX、MIN、COUNT)。

# 四、appendMetricFromResultSet:结果拼装

根据 function 的不同,分为两条路径:

if (f.getReadFunction() == Function.ReadFunction.VALUE) {
  getTimelineMetricsFromResultSet(metrics, f, condition, rs, isEventDownsampledMetric(metricName));
} else {
  SingleValuedTimelineMetric metric =
    TIMELINE_METRIC_READ_HELPER.getAggregatedTimelineMetricFromResultSet(rs, f, isEventDownsampledMetric(metricName));

  if (condition.isGrouped()) {
    metrics.addOrMergeTimelineMetric(metric);
  } else {
    metrics.getMetrics().add(metric.getTimelineMetric());
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
  • VALUE → 原始值查询,走 getTimelineMetricsFromResultSet,从秒表 JSON 中还原时序
  • AVG/SUM/MIN/MAX → 聚合值查询,走 getAggregatedTimelineMetricFromResultSet

# 五、getTimelineMetricsFromResultSet:秒表特殊逻辑

private void getTimelineMetricsFromResultSet(TimelineMetrics metrics, Function f,
   Condition condition, ResultSet rs, boolean shouldSumAcrossTime)
  throws SQLException, IOException {

  if (condition.getPrecision().equals(Precision.SECONDS)) {
    TimelineMetric metric = TIMELINE_METRIC_READ_HELPER.getTimelineMetricFromResultSet(rs);
    if (metric == null) return;

    if (f != null && f.getSuffix() != null) {
      metric.setMetricName(metric.getMetricName() + f.getSuffix());
    }
    if (condition.isGrouped()) {
      metrics.addOrMergeTimelineMetric(metric);
    } else {
      metrics.getMetrics().add(metric);
    }

  } else {
    SingleValuedTimelineMetric metric =
      TIMELINE_METRIC_READ_HELPER.getAggregatedTimelineMetricFromResultSet(rs, f, shouldSumAcrossTime);
    if (condition.isGrouped()) {
      metrics.addOrMergeTimelineMetric(metric);
    } else {
      metrics.getMetrics().add(metric.getTimelineMetric());
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  • 秒表精度:直接取 METRICS JSON 展开为时间序列
  • 非秒表精度:取聚合值列,返回单点数据

# 六、秒表 vs 聚合表差异

表名 字段 说明
METRIC_RECORD_UUID SERVER_TIME, METRICS(JSON) 保存完整时序数据,含所有采样点
METRIC_RECORD_MINUTE_UUID METRIC_SUM, METRIC_MAX... 每分钟聚合值
METRIC_RECORD_HOURLY_UUID 同上 每小时聚合值
METRIC_RECORD_DAILY_UUID 同上 每天聚合值

秒表查询结果(取自 JSON):

image-20250916144949019

非秒表查询结果(取自聚合列):直接返回单值或少量聚合点。

# 七、调用链路梳理

/metrics
  → HBaseAccessor.getMetricRecords
     → PhoenixTransactSQL.prepareGetMetricsSqlStmt
     → METRIC_RECORD_* 表
     → appendMetricFromResultSet
        ├─ getTimelineMetricsFromResultSet (秒表 JSON)
        └─ getAggregatedTimelineMetricFromResultSet (聚合表)
1
2
3
4
5
6
7
#Ambari#Ambari-Metrics#TimelineService#TopN#XOR条件#聚合函数#Controller#Phoenix#HBase
[/metrics] — getAggregateMetricRecords精讲
[/metrics] — 临时指标精讲

← [/metrics] — getAggregateMetricRecords精讲 [/metrics] — 临时指标精讲→

最近更新
01
[/metrics/aggregated] — 聚合数据范围 检查点
09-19
02
[/metrics] — 反向分析接口参数 请求抓包
09-17
03
[/metrics] — 普通指标写入方法 POST
09-17
更多文章>
Theme by Vdoing | Copyright © 2017-2025 JaneTTR | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式