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 的条件非常清晰,只要有问题就告警,没有则不告警。
相关推荐
程序员夏末2 小时前
【MySQL | 第二篇】 MVCC的底层实现(多版本并发控制)
数据库·sql·mysql
油丶酸萝卜别吃2 小时前
MySQL 事务机制深度解析:从 ACID 到底层实现
数据库·mysql
云边有个稻草人2 小时前
【MySQL】第十四节—事务:从基础概念到隔离性理论与实践 | 详解
数据库·mysql·事务·隔离级别·事务的隔离性·事务提交方式
蓝黑20203 小时前
把数据库表里两列的值互换
数据库·sql·mysql
woniu_buhui_fei3 小时前
MySQL知识整理一
数据库·mysql
数据库幼崽3 小时前
ProxySQL官方文档之Architecture Overview
mysql
云计算老刘3 小时前
MySQL 服务器
mysql
V1ncent Chen3 小时前
SQL大师之路 16 集合操作(Union/Intersect/Except)
数据库·sql·mysql·数据分析
Seven973 小时前
MySQL优化全攻略:索引、SQL与分库分表的最佳实践
mysql