ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Apache Doris 监控实战:从一次查询延迟告警看懂 3 个关键指标

Apache Doris 监控实战:从一次查询延迟告警看懂 3 个关键指标

Apache Doris 监控实战:从一次查询延迟告警看懂 3 个关键指标

【免费下载链接】dorisApache Doris is an easy-to-use, high performance and unified analytics database.项目地址: https://gitcode.com/gh_mirrors/dori/doris

一次线上事故复盘:生产 Apache Doris 集群的查询延迟在某次变更后翻倍,值班同学只能靠翻日志猜测原因。问题不在集群本身,而在于集群的指标根本没有被采集。Doris 的 FE 和 BE 默认就暴露 Prometheus 格式的/metrics端点,Prometheus 采集 Doris 指标、Grafana 展示查询延迟趋势,这套 Apache Doris 监控体系搭起来只需要改几个配置文件。

场景导入:一次查不出原因的慢查询

周一上午十点,业务方反馈报表查询从平均 800 毫秒涨到 5 秒以上。你登上 FE 节点,fe.log里没有任何报错,重启服务也没用。事后复盘发现:如果当时有监控,延迟趋势图上 20 分钟的台阶式上涨会直接指向那次 SQL 变更,而不是事后一条条翻 profile。这个场景的教训就是——指标必须先于故障存在。

数据流:Doris 指标从 /metrics 端点走向 Grafana

关键模块在仓库中的位置:

  • FE 指标端点:fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/MetricsAction.java
  • FE 指标注册:fe/fe-core/src/main/java/org/apache/doris/metric/MetricRepo.java
  • BE 指标端点与序列化:be/src/util/metrics.cpp

动手搭建

确认 FE 与 BE 的指标端点

Doris 不需要额外开关,两个端点开箱即用:FE 在http_port(conf/fe.conf 中默认 8030)提供/metrics,BE 在webserver_port(conf/be.conf 中默认 8040)提供同名路径。先用 curl 确认能拿到数据:

curl -s http://<fe_host>:<fe_http_port>/metrics | grep query_latency

输出中应出现# TYPE doris_fe_query_latency_ms summary这一行。

配置 Prometheus 抓取

新增一个抓取 job,scrape_interval建议 15 秒,粒度足够画延迟趋势又不会给 FE 造成明显压力:

global: scrape_interval: 15s scrape_configs: - job_name: doris_fe static_configs: - targets: ['<fe_host>:<fe_http_port>'] labels: cluster: prod component: fe - job_name: doris_be static_configs: - targets: ['<be_host_1>:<be_http_port>', '<be_host_2>:<be_http_port>'] labels: cluster: prod component: be

在 Grafana 上看查询延迟趋势

添加 Prometheus 数据源后,导入社区维护的 Doris 官方看板;或者先建一个最小面板,用这条 PromQL 画 p95 延迟曲线:

doris_fe_query_latency_ms{quantile="0.95"}

关键配置解析

查询延迟是 summary 类型,不是 histogram

这是用 Doris 指标时最常被踩的坑。看 PrometheusMetricVisitor.java 里visitHistogram的实现:延迟指标按 0.75 / 0.95 / 0.98 / 0.99 / 0.999 五个 quantile 直接输出预计算值,外加_sum和_count。它不是 Prometheus 原生的 histogram,所以histogram_quantile()在这里用不了——没有 bucket 可插值。想算平均延迟,用 sum 除以 count:

doris_fe_query_latency_ms_sum / doris_fe_query_latency_ms_count

内存指标靠 type 标签区分 used 和 max

FE 堆内存的jvm_heap_size_bytes用type标签区分状态,写面板时别漏掉这个 label:

sum(jvm_heap_size_bytes{type="used"}) / sum(jvm_heap_size_bytes{type="max"}) by (instance)

BE 侧指标以doris_be_为前缀,具体名称建议直接翻/metrics页面确认后再写进面板,避免版本差异导致查空。

开启 HTTP 认证后,抓取端点会连带被拦

MetricsAction.java 里有一个分支:一旦 FE 配置了enable_all_http_auth = true,/metrics也会要求 Basic Auth,而 Prometheus 默认不带凭证。此时抓取日志里是 401 而不是连接失败,容易被忽略。解法是把认证信息拼进抓取地址:http://<user>:<password>@<fe_host>:<fe_http_port>/metrics。

groups: - name: doris_fe_alerts rules: - alert: FEQueryLatencyP99High expr: doris_fe_query_latency_ms{quantile="0.99"} > 2000 for: 5m labels: severity: warning annotations: summary: "FE p99 查询延迟超过 2 秒"

阈值 2000 毫秒(指标单位是 ms)、持续 5 分钟,是延迟类告警比较稳的起点:太敏感会被偶发慢查询刷爆,太迟钝就失去了提前量。

验证与排障

一条命令验证链路是否通了:

curl -s http://<fe_host>:<fe_http_port>/metrics | grep -E 'query_latency_ms\{quantile="0.99"'

有输出说明 FE 端正常;如果 Grafana 里查不到数据,按下面顺序排查:

现象先检查什么
Prometheus Targets 里目标显示 DOWNhttp_port/webserver_port是否被防火墙拦截,节点是否存活
Targets 正常但查询结果为空是否刚配置还没到第一个 scrape 周期(等待 15~30 秒)
Targets 报 401/UnauthorizedFE 是否开启了enable_all_http_auth,见上文认证小节

想往深走,两条路径:一是在 FE 注册自定义指标,注册逻辑都集中在 MetricRepo.java;二是看 BE 侧指标如何注册与序列化,入口在 util/metrics.cpp。单条慢查询的细粒度分析,再配合 tools/profile_viewer.py 查看查询 profile,监控指标和 profile 两者结合基本能覆盖绝大多数延迟问题。

【免费下载链接】dorisApache Doris is an easy-to-use, high performance and unified analytics database.项目地址: https://gitcode.com/gh_mirrors/dori/doris

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进