prom QL

找出核心业务中,P95 延迟最高的 24 个应用

sql 复制代码
topk_max(24,
    histogram_quantile(0.95, 
      sum(rate(hllci_es_request_seconds_bucket{hll_appid!~"bfe-mvc-logconsumer-svc|bfe-hll-mcv-crash-service-svc|ci-trace-api|bfe-edog-center-api"}[1m])) 
      BY (hll_appid,le)
    ) * 1000
unless on (hll_appid) (cmdb_appid_critical{is_core="1"}))
  • hllci_es_request_seconds_bucket{...}: 这是一个直方图指标(_bucket后缀),用于记录 ES (Elasticsearch) 请求的耗时分布。hll_appid 标签标识了不同的应用。
  • {hll_appid!~"bfe-mvc...}"}: 一个过滤器,使用正则表达式 !~排除后面列出的四个特定的应用(可能是日志消费者、追踪服务等非核心业务应用)。
  • rate(...[1m]): 计算该直方图指标在过去 1 分钟内的每秒增长率。这对于计数器类型的直方图桶是必要操作,因为它会持续增长。
  • sum(...) BY (hll_appid, le): 将速率计算结果按 hll_appid(应用名)和 le(直方桶的边界标签)进行分组求和。这一步是为每个应用构建一个完整的延迟分布。
  • histogram_quantile(0.95, ...): 这是关键函数。它根据上一步生成的延迟分布,为每个应用计算其 P95 分位数。即 95% 的请求耗时低于这个值。
  • * 1000: 将最终结果从 转换为毫秒 ,因为 request_seconds 的单位是秒,而毫秒是更常用的延迟单位。
  • cmdb_appid_critical{is_core="1"}: 查询另一个指标,这个指标可能来自 CMDB(配置管理数据库)或服务注册中心。它标记了哪些应用是核心应用(is_core="1")。
  • unless on (hll_appid): unless 是集合运算符,意思是"排除"。on (hll_appid) 指定了操作所依据的标签。
  • 操作逻辑 :从左边(核心计算部分的结果)的序列中,排除掉 那些其 hll_appid 标签值出现在右边(cmdb_appid_critical 结果)的序列。
  • opk_max(24, ...): 这是一个聚合运算符。它会从内部查询结果中,根据每个时间序列的样本值(即延迟数值),选出数值最大的 24 个。
  • _max 后缀表示它使用每个时间序列在查询时间范围内的最大值来进行排序和选择。

dalGroup 分组,检测在过去一段时间内,是否有任何应用组发生了数据库连接故障(无可用主库)

sql 复制代码
sum(
  topk(50, increase(heartbeat_no_available_master{hll_appid!="ci-dal-regression-test"}[$__interval]))
) BY (dalGroup) > 0
  • heartbeat_no_available_master:这是一个计数器。它的名称表明,它用于记录"无可用主库"的心跳事件。每当一个应用实例检测到其数据库主库不可用时,这个计数器就会增加。
  • {hll_appid!="ci-dal-regression-test"}:一个过滤器,排除掉 hll_appid"ci-dal-regression-test" 的应用。这通常是一个测试环境的应用,排除它是为了避免测试噪声干扰生产监控。
  • [$__interval]:这是一个在 Grafana 中常用的变量。$__interval 会自动被 Grafana 替换为当前图表时间范围内合适的查询步长(例如,查看过去1小时可能为 1m,查看过去7天可能为 1h)。increase(...[$__interval]) 计算的就是在这个动态时间窗口内,该计数器增加的绝对数量
    • 结果 :这部分查询会返回一个区间向量 ,表示在 $__interval 时间内,每个排除测试应用后的序列(通常由 hll_appid, dalGroup 等标签标识)所发生的"无可用主库"事件的总次数。
  • topk(50, ...):这个函数从内层 increase(...) 的结果中,取出计数器值(即无主库事件发生次数)最高的50个时间序列
  • sum(...) BY (dalGroup):将 topk 筛选出的50个最严重的序列,按照 dalGroup(数据库组)这个标签进行分组求和。
    • 这意味着,同一个 dalGroup 下的所有应用实例发生的无主库事件次数会被加在一起 。这非常重要,因为它将监控视角从单个应用实例 提升到了数据库资源组的层面。一个数据库主库挂掉,会影响到所有连接它的应用实例。
  • > 0:这是一个布尔判断。它将上面每个 dalGroup 的求和结果与0进行比较。
    • 如果结果大于0 :返回 1 (表示 true)
    • 如果结果等于0 :返回空集 (表示 false,在Prometheus中不返回数据点)

为什么这是一条优秀的告警规则查询?

  1. 资源维度 :它不是在应用维度告警,而是在数据库资源维度告警。一个主库故障会触发一条告警,而不是成百上千个应用实例各自触发一条告警,避免了告警风暴。
  2. 避免噪声 :通过 topk(50)$__interval 进行了优化,并排除了测试数据。
  3. 明确性> 0 的条件非常清晰,只要有问题就告警,没有则不告警。
相关推荐
OceanWaves199324 分钟前
mysql 8.0.32 磁盘爆满,清理从库日志
数据库·mysql
JavaPub-rodert3 小时前
Go 后台如何同时兼容 MySQL、PostgreSQL、SQLite 和 SQL Server?从 ShiyuAdmin 看 GORM 多数据库适配
数据库·mysql·postgresql·golang·javapub·王仕宇
Code额3 小时前
基于 SQLAlchemy 2.x,面向 MySQL 数据库的从入门到精通实战教程(2)
数据库·sql·mysql·adb·ai
爱吃火鸡面呀4 小时前
MySQL 查询与函数详解:从基础条件筛选到高级字符处理
数据库·mysql
知行产研5 小时前
中国矿山无人驾驶出海的三重门
数据库·mysql·php
爱和冰阔落6 小时前
【MySQL 慢查询排查实战】列表接口逐渐变慢时,怎样从请求链路定位原因
android·数据库·mysql
Dxy12393102166 小时前
MySQL有哪些锁?InnoDB锁体系完整梳理博客
数据库·mysql
wear工程师6 小时前
MySQL 索引条件下推是什么?Using index condition 并不是覆盖索引
sql·mysql
方便面不加香菜7 小时前
MySQL 复合查询
数据库·mysql
花花鱼7 小时前
MySQL Illegal mix of collations 全解|字符集与排序规则冲突原理、分层排错、通用解决方案(适配5.7/8.0迁移)
数据库·mysql